SFINAE - 如果参数是可复制构造的,则启用一个函数,否则启用另一个
SFINAE - enable one function if arguments are copy-constructible and another otherwise
如果参数是可复制构造的,我想调用一个函数和另一个函数(类似于之前的函数,但有额外的代码)。我发现 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;
}
输出:
6NoCopy has copy constructor;
std::is_copy_constructible_v 0
is_copy_constructible_v 似乎在 main 函数内部工作但不在外部
问题是这里的U
不是推导为NoCopy
,而是推导为NoCopy&
。
您可以通过在您的 enable_if
中使用 std::decay_t<U>
来解决这个问题,根据需要去除 cv 限定符和引用并产生 NoCopy
。
如果参数是可复制构造的,我想调用一个函数和另一个函数(类似于之前的函数,但有额外的代码)。我发现 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;
}
输出:
6NoCopy has copy constructor;
std::is_copy_constructible_v 0
is_copy_constructible_v 似乎在 main 函数内部工作但不在外部
问题是这里的U
不是推导为NoCopy
,而是推导为NoCopy&
。
您可以通过在您的 enable_if
中使用 std::decay_t<U>
来解决这个问题,根据需要去除 cv 限定符和引用并产生 NoCopy
。