使用这样的模板时:
class A {...}
class B : A {...}
class C : A {...}
template<typename T>
class D{...}
我需要T只能是B或C.这意味着T必须是A的推导。
有没有办法做到这一点?谢谢!
答案 0 :(得分:5)
使用std::is_base_of
和std::enable_if
:
template<typename T, typename X = std::enable_if<std::is_base_of<A, T>::value>::type>
class D{...}
请注意,只要它来自T
,它就会接受任何A
。如果您需要T
成为B
或C
,则需要对其进行修改,然后使用std::is_same
或/和std::conditional
以及{{1} }}
你可以把它弄清楚:
std::enable_if
其中template<typename T, typename Unused = extends<T,A>>
class D{...}
定义为:
extends
如果您希望它导致错误和编译失败,也可以使用 template<typename D, typename B>
using extends = typename std::enable_if<std::is_base_of<B,D>::value>::type;
(如其他答案所示)。但是,如果您需要选择或取消选择,例如来自许多专业,那么请使用上述方法。
希望有所帮助。
答案 1 :(得分:5)
您可以将static_assert
与std::is_base_of
结合使用:
#include <type_traits>
class A {};
class B : A {};
class C : A {};
class X{};
template<typename T>
class D
{
static_assert(std::is_base_of<A,T>::value, "T must be derived from A");
};
int main()
{
D<C> d_valid;
D<X> d_fails; // compilation fails
return 0;
}
答案 2 :(得分:1)
是的,this应该这样做:
template<typename T>
class D {
static_assert(std::is_base_of<A,T>::value, "not derived from A");
// ...
};
但这不是模板背后的想法。如果你编写模板化的代码,那么它应该是通用的,即。适用于支持您对其应用的操作的所有类型。