之前有一个问题与我的问题相关,该问题与模板类有关,该问题在类原型中声明的方法上使用了std::enable_if
,但实际实现是在外部完成的。
来源:function implementation with enable_if outside of class definition
我想做类似的事情,但要使用类构造函数,我想用std::enable_if
元函数定义外部模板类。
template <typename T>
using EnableIfArithmetic = typename std::enable_if<std::is_arithmetic<T>::value, void>::type;
template <typename NumericType>
class SomeClass {
public:
// constructor definition
template <typename = EnableIfArithmetic<NumericType>>
SomeClass() {
// do some stuff
}
};
所需格式:
template <typename NumericType>
class SomeClass {
public:
// constructor declaration
template <typename = EnableIfArithmetic<NumericType>>
SomeClass();
};
// constructor definition
template <typename NumericType>
template <typename = EnableIfArithmetic<NumericType>>
SomeClass<NumericType>::SomeClass() {
// constructor implementation
}
但是我不能正确地做到这一点,没有编译错误。我究竟做错了什么?
答案 0 :(得分:0)
模板参数的默认值不应在定义中重复。例如:
template<typename N>
struct S {
template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
S(T);
};
template<typename N>
template<typename T, typename>
S<N>::S(T) { }
使用SFINAE的方式不正确:EnableIfArithmetic
应该取决于某种推断的类型(在同一模板中)。请参阅this question。例如:
template<typename T = N, typename = EnableIfArithmetic<T>>
S() { }
否则,将发生严重失败:
错误:“ struct std :: enable_if”中没有名为“ type”的类型
如果要为某些类型N
禁用默认构造函数,则还可以在构造函数内部使用static_assert
。但是,它将不是SFINAE友好的。
template<typename N>
struct S1 {
public:
template<typename T = N, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
S1() { }
};
template<typename N>
struct S2 {
public:
S2() { static_assert(std::is_arithmetic_v<N>); }
};
static_assert(std::is_default_constructible_v<S1<int>>);
static_assert(!std::is_default_constructible_v<S1<void>>);
static_assert(std::is_default_constructible_v<S2<int>>);
static_assert(std::is_default_constructible_v<S2<void>>);