SFINAE - 如果参数是可复制构造的,则启用一个函数,否则启用另一个函数

joh*_*456 0 c++ templates copy-constructor c++17

如果参数是可复制构造的,我希望调用一个函数和另一个函数(类似于前面的但有额外的代码)。我发现 std::is_copy_constructible 没有按预期工作

#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;
}


                                                                                                                                                                                                                                    
Run Code Online (Sandbox Code Playgroud)

输出:

6NoCopy 有复制构造函数;
std::is_copy_constructible_v 0

is_copy_constructible_v 似乎在 main 函数内部工作但不在外部

Jer*_*man 5

问题是这里U不是推导为NoCopy,而是推导为NoCopy&

您可以通过使用std::decay_t<U>in your enable_ifto strip the cv qualifiers and reference and yield来解决这个问题NoCopy