C ++ 11模板条件

时间:2015-09-27 10:14:31

标签: templates c++11

我想用有条件的数字编写模板。

//in header file
template <typename T,
    typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type 
>
class Foo
{
    public:
        Foo();
};

#include "Foo.inline"

//In inline file
template <
    typename T
>
Foo<T>::Foo()
{
};

但是,这不会编译。如何在单独的文件中使用模板实现语法?

3 个答案:

答案 0 :(得分:3)

std::enable_if对于触发替换失败非常有用,因此编译器可以回退到另一个重载/特化。

如果要验证模板参数,请在static_assert

中添加适当的条件
template <typename T>
class Foo
{
    static_assert(std::is_arithmetic<T>::value,
                  "T must be an arithmetic type");
public:
    Foo();
};

template <typename T>
Foo<T>::Foo()
{
}

答案 1 :(得分:1)

第二个模板参数应该在定义中使用。

//in header file
template <typename T,
    typename Enable = typename std::enable_if<std::is_arithmetic<T>::value, T>::type
>
class Foo
{
    public:
        Foo();
};


//In inline file
template <typename T, typename Enable>
Foo<T, Enable>::Foo()
{
};

答案 2 :(得分:1)

您的代码存在的问题是,如果第一个模板参数满足T,则会将第二个模板参数默认为is_arithmetic。这适用于案例1但不适用于案例2

template <typename T, 
          typename U = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
class Foo {
    public:
        Foo();
};

template <typename T, typename U>
Foo<T, U>::Foo() {
}

struct Obj {};

int main() {
    Foo<int> obj; // Fine
    // Foo<Obj> obj2 // 1) Error - as it should be
    Foo<std::string, Obj> obj3; // 2) Works fine - bad
}

Live Example

为了避免实例化,如果第一个类型对is_arithmetic无效,则应使用static_assert

template <typename T>
class Foo {
    static_assert(std::is_arithmetic<T>::value, "T is not an arithmetic type");
    public:
        Foo();
};

template <typename T>
Foo<T>::Foo() {
}

Live Example