我尝试创建一个模板类,它应该使用 SFINAE 和可变参数模板检测任何构造函数。这是模板的代码:
template <typename Type, typename ... Arguments>
struct IsConstructible
{
template <typename U, decltype(U(Arguments...))* = nullptr>
static char test();
template <typename U>
static long test(...);
static constexpr bool value = sizeof(test<Type>()) == sizeof(char);
};
但是,当我使用以下类型对此进行测试时:
struct MyBadType {
MyBadType(int x) { }
};
结果:
IsConstructible<MyBadType, int>::value;
是 0。我的模板检查器有什么问题吗?我正在使用 MSVS 2015 Express。
最佳答案
代码不应该编译;如果 MSVC 这样做,那么它正在使用扩展。
template <typename U, decltype(U(Arguments...))* = nullptr>
那个decltype
表达没有意义。 U(Arguments...)
是一个函数类型,但是你想获取构造一个U
的类型来自 Arguments...
.你可以使用 std::declval
为此:
template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr>
还有第二个问题:
template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr>
static char test();
template <typename U>
static long test(...);
电话test<type>()
会模棱两可。解决歧义的“经典”方法是为首选版本提供一个虚拟参数:
template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr>
static char test(int);
// here ^^^
template <typename U>
static long test(...);
然后你调用像test<type>(0)
这样的函数.
参见 this blog post以更灵活的方式解决重载歧义。
关于C++使用SFINAE检测任何构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36177951/