c++ - 为什么模板参数中的 enable_if_t 提示重新定义?

标签 c++ templates c++14 sfinae enable-if

我有以下使用 std::enable_if 的案例:

template<typename T,
         typename std::enable_if<std::is_same<int, T>::value>::type* = nullptr>
void f() { }

template<typename T,
         typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr>
void f() { }

现在,我在 cppreference 中看到了新语法,在我看来更简洁:typename = std::enable_if_t<std::is_same<int, T>::value>>

我想移植我的代码:

template<typename T,
         typename = std::enable_if_t<std::is_same<int, T>::value>>
void g() { }

template<typename T,
         typename = std::enable_if_t<std::is_same<double, T>::value>>
void g() { }

但现在 GCC (5.2) 提示:

error: redefinition of 'template<class T, class> void g()'
       void g() { }

为什么会这样?如果可能的话,在这种情况下,我能做些什么来获得新的、更简洁的语法?

最佳答案

让我们删除一些代码。

template<
  class T,
  class U/* = std::enable_if_t<std::is_same<int, T>::value>*/
 >
void g() { }

template<
  class T,
  class U/* = std::enable_if_t<std::is_same<double, T>::value>*/
 >
void g() { }

如果编译器拒绝了上述两个模板,你会感到惊讶吗?

它们都是“类型”的模板函数template<class,class>void() .第二种类型参数具有不同的 default 值这一事实并不重要。这就像期待两个不同的 print(string, int)具有不同默认值的函数 int值过载。 ;)

在第一种情况下,我们有:

template<
  typename T,
  typename std::enable_if<std::is_same<int, T>::value>::type* = nullptr
>
void f() { }

template<
  typename T,
  typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr
>
void f() { }

这里我们不能删除 enable_if条款。更新到 enable_if_t :

template<
  class T,
  std::enable_if_t<std::is_same<int, T>::value, int>* = nullptr
>
void f() { }

template<
  class T,
  std::enable_if_t<std::is_same<double, T>::value, int>* = nullptr
>
void f() { }

我还替换了 typename 的用法与 class .我怀疑你的困惑是因为 typename有两个含义——一个作为一种template的标记。参数,另一个作为依赖类型的消歧器。

这里的第二个参数是一个指针,它的类型取决于第一个。如果不先替换 T 类型,编译器无法确定这两个是否冲突。 -- 你会注意到它们实际上永远不会发生冲突。

关于c++ - 为什么模板参数中的 enable_if_t 提示重新定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31500426/

相关文章:

c++ - 将 char 缓冲区安全(独立于平台)到 std::string

C++ std::map s 作为参数

C++——我们为什么要在此构造函数中使用 explicit?

c++ - OpenCV C++ - Windows IDE

c++ - 为什么非常量 std::array::operator[] 不是 constexpr?

c++ - 启用 C++14 英特尔编译器

c++ - OpenCV + CUDA + OSX 小牛队

Android Studio 自定义模板

C++ 模板和继承

templates - Liferay 门户 6.2 - 用于显示知识库文章的 Assets 发布者模板