Stack Exchange
SFINAE - enable one function if arguments are copy-constructible and another otherwise
I want a function to be called if the argument are copy-constructible and another function (similar to previous but with extra code). I find that std::is_copy_constructible is not working as expected
#include <iostream>

using namespace std;


struct NoCopy {
    int n;
    NoCopy(const NoCopy&) = delete;
};


template <typename T, 
         typename U, 
         std::enable_if_t<!std::is_copy_constructible_v<U>, int> = 0>
void log_debug(T&& t, U&& u)
{
    
 std::cout<<"\n"<<typeid(U).name()<<" does not have copy constructor; ";  
}
   
   
template <typename T, 
            typename U, 
            std::enable_if_t<std::is_copy_constructible_v<U>, int> = 0>
void log_debug(T&& t, U&& u)
{
    
 std::cout<<"\n"<<typeid(U).name()<<" has copy constructor; ";  
}

int main()
{
    NoCopy a{2};
    log_debug("value is ", a);
    
    std::cout<<"\nstd::is_nothrow_copy_constructible_v  "<<std::is_copy_constructible_v<NoCopy>;  //returns 0 as expected

    return 0;
}


                                                                                                                                                                                                                                    

Output:

6NoCopy has copy constructor;
std::is_copy_constructible_v  0

is_copy_constructible_v   seems to work inside main function but not outside

The problem is that here U isn't deduced as NoCopy, but as NoCopy&.
You can fix this by using std::decay_t<U> in your enable_if to strip the cv qualifiers and reference and yield NoCopy like you want.
