为什么模板参数中的enable_if_t抱怨重新定义? [英] Why does enable_if_t in template arguments complains about redefinitions?

查看:68
本文介绍了为什么模板参数中的enable_if_t抱怨重新定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况可以使用 std :: enable_if

I have the following case that works using 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>>>

Now, I saw in cppreference the new syntax, much cleaner in my opinion : 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)抱怨:

But now GCC (5.2) complains :

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

为什么这样?在这种情况下,如果可以的话,我该怎么做才能拥有新的,更简洁的语法?

Why is that so ? What can I do to have the new, more concise syntax in this case if this is possible ?

推荐答案

让我们删除一些代码。

Let's remove some code.

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() { }

如果编译器拒绝了以上两个,您会感到惊讶吗

would you be surprised if the compiler rejected the two above templates?

它们都是类型 template< class,class> void()的模板函数。第二类型参数具有不同的 default 值的事实无关紧要。这就像期望两个具有不同的默认 int 值的 print(string,int)函数重载一样。 ;)

They are both template functions of "type" template<class,class>void(). The fact that the 2nd type argument has a different default value matters not. That would be like expecting two different print(string, int) functions with different default int values to overload. ;)

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

In the first case we have:

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

here we cannot remove the enable_if clause. Updating to 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 自变量的标记,以及

I also replaced a use of typename with class. I suspect your confusion was because typename has two meanings -- one as a marker for a kind of template argument, and another as a disambiguator for a dependent type.

这里的第二个参数是一个指针,其类型取决于第一个。编译器在没有先替换为 T 类型之前就无法确定这两个是否冲突-您将注意到它们永远不会真正冲突。

Here the 2nd argument is a pointer, whose type is dependent on the first. The compiler cannot determine if these two conflict without first substituting in the type T -- and you'll note that they will never actually conflict.

这篇关于为什么模板参数中的enable_if_t抱怨重新定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆