c++ - 在由另一个构造函数创建的模板类中实例化未使用的构造函数

标签 c++ templates void sfinae enable-if

我有以下类(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& 。这显然是不允许的。

如何防止第二个构造函数有效,如果 Tvoid

最佳答案

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/

相关文章:

c++ - Template Explicit Specialization 和普通函数有什么区别?

c - 从 double 函数返回 void?

c# - 我不明白 "protected void Page_Load"是什么

c++ - 指针取消引用开销与分支/条件语句

c++ - GLM Math lib 使用 GCC 编译错误

c++ - 如何为编译时已知的参数的多个值编译函数

c - 如何将字符指针数组作为 void * 传递,然后转换回字符指针数组?

c++ - 在golang调用DLL?

java - 在 C++ 中使用 Java 作为 “scripting” 语言

c++ - 正确的 C++ 方法来存储多类型数据