为什么模板参数中的 enable_if_t 会抱怨重新定义?

Why does enable_if_t in template arguments complains about redefinitions?(为什么模板参数中的 enable_if_t 会抱怨重新定义?)
本文介绍了为什么模板参数中的 enable_if_t 会抱怨重新定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

template::value>::type* = nullptr>无效 f() { }模板<类型名 T,typename std::enable_if::value>::type* = nullptr>无效 f() { }

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

我想移植我的代码:

template::value>>无效 g() { }模板<类型名 T,typename = std::enable_if_t::value>>无效 g() { }

但现在 GCC (5.2) 抱怨:

error: redefinition of 'template空 g()'无效 g() { }

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

解决方案

让我们删除一些代码.

模板::value>*/>无效 g() { }模板::value>*/>无效 g() { }

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

它们都是类型"的模板函数templatevoid().第二种类型参数具有不同的默认值这一事实无关紧要.这就像期望两个不同的 print(string, int) 函数具有不同的默认 int 值来重载.;)

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

模板<类型名称 T,typename std::enable_if::value>::type* = nullptr>无效 f() { }模板<类型名称 T,typename std::enable_if::value>::type* = nullptr>无效 f() { }

这里我们不能删除 enable_if 子句.更新到 enable_if_t:

模板::value, int>* = nullptr>无效 f() { }模板::value, int>* = nullptr>无效 f() { }

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

这里的第二个参数是一个指针,它的类型依赖于第一个.编译器无法在不首先替换类型 T 的情况下确定这两者是否冲突——并且您会注意到它们实际上永远不会发生冲突.

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

Now, I saw in cppreference the new syntax, much cleaner in my opinion : typename = std::enable_if_t<std::is_same<int, T>::value>>

I wanted to port my code :

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

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?

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

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

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.

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 会抱怨重新定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How do compilers treat variable length arrays(编译器如何处理变长数组)
Deduce template argument from std::function call signature(从 std::function 调用签名推导出模板参数)
check if member exists using enable_if(使用 enable_if 检查成员是否存在)
Standard Library Containers with additional optional template parameters?(具有附加可选模板参数的标准库容器?)
Uses of a C++ Arithmetic Promotion Header(C++ 算术提升标头的使用)
Parameter pack must be at the end of the parameter list... When and why?(参数包必须位于参数列表的末尾...何时以及为什么?)