我正在尝试禁用具有非 std::string 可构造类型的 ctor。我的第一次尝试是这样的:
#include <iostream>
struct A
{
template <typename U, typename = typename std::enable_if<std::is_constructible<std::string, U>::value>::type>
A(U&& val)
{
std::cout << "A(std::string&& val)" << std::string(std::forward<U>(val)) << std::endl;
}
template <typename U, typename = typename std::enable_if<not std::is_constructible<std::string, U>::value>::type>
A(U&& val)
{
std::cout << "A(int&& val)" << val << std::endl;
}
};
int main()
{
A a1(1);
A a2("hello");
A a3(std::string("hello"));
}
但是编译失败了
A a1(1);
并出现以下错误消息:
错误 C2535: 'A::A(U &&)': 成员函数已定义或声明 (活生生的例子 https://wandbox.org/permlink/IVKLqPY1aSj5Zt5q).
这意味着 SFINAE 的两个条件都成功,并且两个因子都被使用。
我继续尝试以下方法:
#include <iostream>
struct A
{
template <typename U>
A(U&& val, typename std::enable_if<std::is_constructible<std::string, U>::value>::type* = nullptr)
{
std::cout << "A(std::string&& val)" << std::string(std::forward<U>(val)) << std::endl;
}
template <typename U>
A(U&& val, typename std::enable_if<not std::is_constructible<std::string, U>::value>::type* = nullptr)
{
std::cout << "A(int&& val)" << val << std::endl;
}
};
int main()
{
A a1(1);
A a2("hello");
A a3(std::string("hello"));
}
幸运的是它编译并运行良好(活生生的例子 https://wandbox.org/permlink/yq67DhcV6l2GQi6O).
到目前为止,我对第二个解决方案非常满意,但我不太明白为什么使用模板化参数启用/禁用 ctor 的第一种方法不起作用。