在 VS2015 中键入 SFINAE 编译,但生成错误
Type SFINAE in VS2015 compiles, but generates error
我做了两个测试类:
class Class1
{
public:
Class1(int a) {}
};
class Class2
{
public:
Class2() {}
};
还有两个模板函数使用类型 SFINAE 来决定使用哪个。如果 T 不是默认构造的,第二个将 "fail"。
template<typename T>
T* CreateInstanceTest(char*[!std::is_default_constructible<T>::value] = 0) { return nullptr; }
template<typename T>
T* CreateInstanceTest(char*[std::is_default_constructible<T>::value] = 0) { return new T(); }
然后我这样做:
Class1* obj1 = CreateInstanceTest<Class1>();
Class2* obj2 = CreateInstanceTest<Class2>();
生成错误 "more than one instance of overloaded function "CreateInstanceTest" matches the argument list"。
但是,它可以正常编译并按预期工作。 obj1 变为 null 并正确创建 obj2。
为什么会这样?有什么办法可以解决这个问题吗?
这是一个智能感知错误,不是构建错误。 Intellisense 并不完美,但作为解决方法,您可以改进推导代码:
template<typename T> typename ::std::enable_if_t
<
!::std::is_default_constructible<T>::value
, T *
>
CreateInstanceTest(void) { return nullptr; }
template<typename T> typename ::std::enable_if_t
<
::std::is_default_constructible<T>::value
, T *
>
CreateInstanceTest(void) { return new T(); }
我做了两个测试类:
class Class1
{
public:
Class1(int a) {}
};
class Class2
{
public:
Class2() {}
};
还有两个模板函数使用类型 SFINAE 来决定使用哪个。如果 T 不是默认构造的,第二个将 "fail"。
template<typename T>
T* CreateInstanceTest(char*[!std::is_default_constructible<T>::value] = 0) { return nullptr; }
template<typename T>
T* CreateInstanceTest(char*[std::is_default_constructible<T>::value] = 0) { return new T(); }
然后我这样做:
Class1* obj1 = CreateInstanceTest<Class1>();
Class2* obj2 = CreateInstanceTest<Class2>();
生成错误 "more than one instance of overloaded function "CreateInstanceTest" matches the argument list"。
但是,它可以正常编译并按预期工作。 obj1 变为 null 并正确创建 obj2。
为什么会这样?有什么办法可以解决这个问题吗?
这是一个智能感知错误,不是构建错误。 Intellisense 并不完美,但作为解决方法,您可以改进推导代码:
template<typename T> typename ::std::enable_if_t
<
!::std::is_default_constructible<T>::value
, T *
>
CreateInstanceTest(void) { return nullptr; }
template<typename T> typename ::std::enable_if_t
<
::std::is_default_constructible<T>::value
, T *
>
CreateInstanceTest(void) { return new T(); }