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
?如果您希望它导致错误和编译失败,也可以使用它。但是如果您需要选择,请hen
std::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");
 // ...
};