C++ c++;模板专门化和派生
使用这样的模板时:C++ c++;模板专门化和派生,c++,templates,C++,Templates,使用这样的模板时: class A {…} class B : A {…} class C : A {…} template<typename T> class D{…} A类{…} B类:A{…} C类:A{…} 模板 类D{…} 我需要T只能是B或C,这意味着T必须是a的导数 有没有办法做到这一点?谢谢 使用std::is_base_of以及std::enable_if: template<typename T, typename X = std::enable_if
class A {…}
class B : A {…}
class C : A {…}
template<typename T>
class D{…}
A类{…}
B类:A{…}
C类:A{…}
模板
类D{…}
我需要T只能是B或C,这意味着T必须是a的导数
有没有办法做到这一点?谢谢 使用
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{...}
其中,扩展
定义为:
template<typename D, typename B>
using extends = typename std::enable_if<std::is_base_of<B,D>::value>::type;
模板
使用extends=typename std::enable_if::type;
如果希望导致错误和编译失败,也可以使用
static\u assert
(与其他答案一样)。但是,如果您需要选择或取消选择,比如从许多专门化中选择,则使用上述方法
希望对您有所帮助。您可以结合使用:
#包括
A类{};
B类:A{};
C类:A{};
类X{};
模板
D类
{
static_assert(std::is_base_of是,应该这样做:
template<typename T>
class D {
static_assert(std::is_base_of<A,T>::value, "not derived from A");
// ...
};
模板
D类{
静态断言(std::is_base_of
但是这不是模板背后的想法。如果您编写模板化代码,那么它应该是泛型的,即适用于支持您应用于它们的操作的所有类型。为什么不static\u assert
?如果您希望它导致错误和编译失败,也可以使用它。但是如果您需要选择,请henstd::enable_if
。我更喜欢static_assert
,因为它更干净而且有保证。使用上述解决方案,请考虑D;
用户可以绕过它(un)有意地。@iammilind:正如我所说,解决方案不是等价的。因此,这不仅仅是偏好。这是设计。好吧,编写对泛型类型T做出假设的泛型代码是合法的。所有关于“概念”的大惊小怪都是关于如何在语言中引入它。的确,但已经有人支持这种假设的模型可以按一定的层次顺序排列:继承的“is-a”关系。当然继承并不总是这样,但我猜情况并非如此。概念更多的是关于“横切”属性,比如可移动但不可复制。
#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;
}
template<typename T>
class D {
static_assert(std::is_base_of<A,T>::value, "not derived from A");
// ...
};