模板 class 构造函数定义 enable_if 在 class 原型之外
template class constructor definition with enable_if outside class prototype
有一个问题与我之前的问题有点相关,它涉及模板 class,它在 class 原型中声明的方法上使用了 std::enable_if
,但是实际实施是在外面完成的。
来源:
我想做类似的事情,但是使用 class 构造函数,我想用 std::enable_if
元函数定义外部模板 class。
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
}
但我做对了,没有编译错误。我究竟做错了什么?
模板参数的默认值不应在定义中重复。例如:
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
应该取决于某些推导类型(在同一模板中)。请参考。例如:
template<typename T = N, typename = EnableIfArithmetic<T>>
S() { }
否则会发生硬故障:
error: no type named 'type' in 'struct std::enable_if'
如果要禁用某些类型的默认构造函数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>>);
有一个问题与我之前的问题有点相关,它涉及模板 class,它在 class 原型中声明的方法上使用了 std::enable_if
,但是实际实施是在外面完成的。
来源:
我想做类似的事情,但是使用 class 构造函数,我想用 std::enable_if
元函数定义外部模板 class。
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
}
但我做对了,没有编译错误。我究竟做错了什么?
模板参数的默认值不应在定义中重复。例如:
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
应该取决于某些推导类型(在同一模板中)。请参考
template<typename T = N, typename = EnableIfArithmetic<T>>
S() { }
否则会发生硬故障:
error: no type named 'type' in 'struct std::enable_if'
如果要禁用某些类型的默认构造函数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>>);