假设我有一个class A
模板,如下所示:
template<typename T>
class A
{
T data;
public:
void func(){} //concerned function ** see here **
};
现在我有另一个class B
模板,比如
template<typename U>
class B
{
// ... something whatever
};
这意味着不构建函数的条件是直接模板typename T
是B
。 C
可以是任何类型,包括A
和B
。
答案 0 :(得分:2)
除非使用了odr,否则不会生成类模板的成员函数。这是机制力量的一部分。
如果您想限制使用此成员函数,那么您确实会使用std::is_same
。诀窍是定义适当的特征/元函数:
template<class, template<class...> class>
struct is_template_instance : std::false_type {};
template<template<class...> class T, class... Cs>
struct is_template_instance<T<Cs...>, T> : std::true_type {};
真正的专业化只会选择is_template_instance<std::vector<int>, std::vector>
之类的东西。现在只需使用静态断言或std::enable_if
:
auto func() ->
typename std::enable_if<!is_template_instance<T, B>::value>::type {
}
答案 1 :(得分:1)
您需要partial specialize模板:
template<typename C>
class A<B<C>> // Used when A<B<C>> is instantiated
{
B<C> data;
};
唯一的缺点是这需要一些代码重复,这并非总是可行。
相反,您可以创建一个具有所有功能的基类,并从该基础派生:
// Base class with all the common functionality.
template<typename T>
class A_impl
{
protected:
T data;
};
// Special case when 'func' is available.
template<typename T>
class A : public A_impl<T>
{
public:
void func() {}
};
// Another special case where 'func' is not available.
template<typename C>
class A<B<C>> : public A_impl<B<C>> {
};