我有以下类(class):
template <typename T=void>
class Foo{
public:
Foo(){};
template <typename = typename std::enable_if_t<!std::is_void<T>::value, std::nullptr_t>>
Foo(const T&){};
};
int main() {
Foo<void> v;
}
v
使用第一个构造函数创建。因此,不需要为Foo<void>
创建第二个构造函数。 .
为什么它还是被创建了?
问题在于显式创建类型 void
的第二个构造函数绕过SFINAE,并尝试将参数设置为const void&
。这显然是不允许的。
如何防止第二个构造函数有效,如果 T
是 void
?
最佳答案
Why does it get created anyways?
因为在你的模板构造函数中
template <typename = typename std::enable_if_t<!std::is_void<T>::value, std::nullptr_t>>
Foo(const T&){};
std::enable_if
的测试值( !std::is_void<T>::value
) 取决于类的模板类型 ( T
)。
要 SFINAE 启用/禁用类(或结构)的方法,您必须编写一个依赖于方法本身的模板参数的测试。
规避此问题的一种方法是添加模板参数 U
方法并给出 T
作为默认类型。我的意思是
template <typename U = T,
typename = std::enable_if_t<!std::is_void<U>::value, std::nullptr_t>>
Foo(const U&){} // ..... the test depends from U ---^
// ^--- U also here, to avoid the void reference problem
或者,也许更好,
template <typename U = T,
std::enable_if_t<!std::is_void<U>::value, std::nullptr_t> = nullptr>
Foo(const U&){}
关于c++ - 在由另一个构造函数创建的模板类中实例化未使用的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70920762/