c ++模板专业化和派生

时间:2015-08-06 06:53:08

标签: c++ templates

使用这样的模板时:

class A {...}
class B : A {...}
class C : A {...}

template<typename T>
class D{...}

我需要T只能是B或C.这意味着T必须是A的推导。

有没有办法做到这一点?谢谢!

3 个答案:

答案 0 :(得分:5)

使用std::is_base_ofstd::enable_if

template<typename T, typename X = std::enable_if<std::is_base_of<A, T>::value>::type>
class D{...}

请注意,只要它来自T,它就会接受任何A。如果您需要T成为BC,则需要对其进行修改,然后使用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_assertstd::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;
}

live on ideone

答案 2 :(得分:1)

是的,this应该这样做:

template<typename T>
class D {
 static_assert(std::is_base_of<A,T>::value, "not derived from A");
 // ...
};

Demo here.

这不是模板背后的想法。如果你编写模板化的代码,那么它应该是通用的,即。适用于支持您对其应用的操作的所有类型。