为什么模板参数中的enable_if_t会抱怨重定义
Why does enable_if_t in template arguments complains about redefinitions?
我有以下使用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()
的模板函数。第二个类型参数具有不同的默认值这一事实无关紧要。这就像期望两个具有不同默认int
值的不同print(string, 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() { }
我还用class
代替了typename
的使用。我怀疑你的困惑是因为typename
有两个含义——一个是作为一种template
参数的标记,另一个是作为依赖类型的消歧器。
第二个参数是一个指针,它的类型依赖于第一个参数。如果不首先替换类型T
,编译器无法确定这两者是否冲突——您将注意到它们实际上永远不会冲突。
enable_if_t<B>
只是typename enable_if<B>::type
的别名。让我们把它代入g
,这样我们就可以看到f
和g
之间的真正区别:
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() { }
template<typename T,
typename = typename std::enable_if<std::is_same<int, T>::value>::type>
void g() { }
template<typename T,
typename = typename std::enable_if<std::is_same<double, T>::value>::type>
void g() { }
在f
的例子中,我们有两个函数模板,它们都带有模板形参<typename, X*>
,其中X
的类型依赖于第一个模板实参的类型。在g
的例子中,我们有两个带有模板形参<typename, typename>
的函数模板,并且只有默认模板实参是相互依赖的,因此c++认为它们都声明了同一个实体。
任何一种样式都可以与enable_if_t
别名一起使用:
template<typename T,
std::enable_if_t<std::is_same<int, T>::value>* = nullptr>
void f() { }
template<typename T,
std::enable_if_t<std::is_same<double, T>::value>* = nullptr>
void f() { }
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() { }
对于函数返回类型,您要查找以下内容:
template<typename T> std::enable_if_t< conditional, instantiation result > foo();
的例子:
#include <iostream>
// when T is "int", replace with 'void foo()'
template<typename T>
std::enable_if_t<std::is_same<int, T>::value, void> foo() {
std::cout << "foo intn";
}
template<typename T>
std::enable_if_t<std::is_same<float, T>::value, void> foo() {
std::cout << "foo floatn";
}
int main() {
foo<int>();
foo<float>();
}
http://ideone.com/TB36gH 参见
http://ideone.com/EfLkQy你失踪"::". .
template<typename T,
typename = std::enable_if_t<std::is_same<int, T>::value>::type>
void g() { }
template<typename T,
typename = std::enable_if_t<std::is_same<double, T>::value>::type>
void g() { }
相关文章:
- c++:定义if语句中的模板
- 获取 if 语句以检查定义的宏
- 如何在C++中为 if 和 else 语句定义新行为
- 如何定义此"if block"中其他无效输入的值,以便在c ++中将字符串转换为对象?
- 是否应该定义 #if 中使用的宏?
- c if语句:第一个条件取代第二个ub或定义良好
- 在"if"条件中定义 fstream
- C 使用功能定义中的if/其他语句以返回最小的数字
- 为什么我不能在 If 语句中定义多个变量以相互相等?
- C多行宏问题:为什么不使用if(1){..}而不是do{..}while(0)在多行宏定义中
- 奇怪的错误:标签'loopend'使用但未定义," if "之前应为非限定 id("goto"和" '}' token "错误相同
- 如何在 if 条件中区分零和未定义
- 如何在if/else序列中定义未知类型的全局变量
- C++对方法和What-if所有东西都转到.h的未定义引用
- 为什么if语句中未定义的参数不会导致segfault或其他错误
- 自定义C++谓词并查找if
- 获取 while、if 和 for 语句的用户定义类的对象值
- 0 && 定义(_LP64)#if 如何为真?
- 为什么定义 #if 0 && (_MSC_VER > 1000)?
- 定义 if 块内部的常量"variable"