我想用有条件的数字编写模板。
//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()
{
};
但是,这不会编译。如何在单独的文件中使用模板实现语法?
答案 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
}
为了避免实例化,如果第一个类型对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() {
}