2

我有一个模板类,我想根据模板参数启用不同的构造函数。具体来说,我想以此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>::valueis false.

为什么std::enable_if似乎无法正常工作?

4

1 回答 1

5

typename T::value_type&,T不能被 代替double。由于T是类模板的模板参数而不是构造函数模板的模板参数,因此您无法通过替换失败排除重载。SFINAE 仅在涉及相关模板的参数时才有效。

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

于 2013-09-18T09:41:38.587 回答