C++ 带有'std::enable_if<;的意外SFINAE行为;std::是_化合物<;双重>;::价值>`

C++ 带有'std::enable_if<;的意外SFINAE行为;std::是_化合物<;双重>;::价值>`,c++,c++11,C++,C++11,我有一个模板类,我想根据模板参数为其启用不同的构造函数。具体来说,我想使用std::is_component作为标准 SSCCE //bla.cpp #包括 #包括 模板 福班{ 双杠; 公众: 模板 Foo(typename T::value_type&b):bar(b){} 模板::类型 > Foo(tb):bar(b){} }; int main(){ 双d=1.0; Foo f2(d);//工作 Foo f1(d);//编译器错误 } 我发现以下编译错误: g++-std=gnu++1

我有一个模板类,我想根据模板参数为其启用不同的构造函数。具体来说,我想使用
std::is_component
作为标准

SSCCE
//bla.cpp
#包括
#包括
模板
福班{
双杠;
公众:
模板
Foo(typename T::value_type&b):bar(b){}
模板::类型
>
Foo(tb):bar(b){}
};
int main(){
双d=1.0;
Foo f2(d);//工作
Foo f1(d);//编译器错误
}
我发现以下编译错误:

g++-std=gnu++11 bla.cpp

bla.cpp: In instantiation of ‘class
Foo<double>’: bla.cpp:22:18:   required from here bla.cpp:11:2: error:
‘double’ is not a class, struct, or union type
bla.cpp:在“类”的实例化中
Foo':bla.cpp:22:18:此处需要bla.cpp:11:2:错误:
“double”不是类、结构或联合类型

问题似乎是正在使用构造函数的第一个版本,这失败了,因为
double::value\u type
不存在。问题是构造函数首先不应该在
Foo
中,因为
std::is_component::value
false


如果
似乎工作不正常,为什么
std::enable\u?

typename T::value\u type&
中,
T
不能用
double
代替。由于
T
是类模板的模板参数,而不是构造函数模板的模板参数,因此不能通过替换失败排除重载。SFINAE仅在涉及相关模板的参数时有效


如果您使用
typename U::value\U type&
,您会得到一个不是错误的替换失败,因为
U
是构造函数模板的参数,而不是类模板的参数。

在这种情况下,是否仍然可以强制执行类型
U
必须等于type
T
?在这种情况下,似乎可以接受任何复合类型?我认为伪参数
U=T
可以解决这个问题(例如,SFINAE仍然可以处理
U
)。@MarcClaesen因为您无法将显式模板参数传递给构造函数模板,所以U不可能是T。@MarcClaesen我认为您需要的是
std::enable_if
(对于其他构造函数也是如此),但这只是为您自己的类
Foo
启用特性,如
是可构造的。
bla.cpp: In instantiation of ‘class
Foo<double>’: bla.cpp:22:18:   required from here bla.cpp:11:2: error:
‘double’ is not a class, struct, or union type