我有一个模板类,我想根据模板参数启用不同的构造函数。具体来说,我想使用 std::is_compound
作为标准。
SSCCE
// bla.cpp
#include <type_traits>
#include <vector>
template <typename T>
class Foo{
double bar;
public:
template<typename U=T,
class = typename std::enable_if<std::is_compound<U>::value>::type
>
Foo(typename T::value_type& b):bar(b){}
template<typename U=T,
class = typename std::enable_if<!std::is_compound<U>::value>::type
>
Foo(T b):bar(b){}
};
int main(){
double d=1.0;
Foo<std::vector<double>> f2(d); // works
Foo<double> f1(d); // compiler error
}
我收到以下编译错误:
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
问题似乎是正在使用构造函数的第一个版本,该版本失败,因为 double::value_type
不存在。问题是该构造函数不应该位于 Foo<double>
中首先,因为std::is_compound<double>::value
是 false
。
为什么std::enable_if
好像工作不正常?
最佳答案
在typename T::value_type&
中,T
不能被double
替代。由于 T
是类模板的模板参数,而不是构造函数模板的模板参数,因此您无法通过替换失败排除重载。 SFINAE 仅在涉及相关模板的参数时才起作用。
如果您使用 typename U::value_type&
,则会出现替换失败,但这不是错误,因为 U
是构造函数模板的参数,而不是类的参数模板。
关于c++ - `std::enable_if<std::is_compound<double>::value>` 出现意外的 SFINAE 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18868647/