给出一个C ++类:
template<typename T>
class A {
public:
int a;
T x;
int getA() {return a;}
};
模板专门化是否有可能从A继承'(没有实际的C ++继承)成员,如a和getA()?此外,在编写为类执行大量模板特化的代码时,我应该多次键入相同的代码(这有点会破坏模板的整个目的),或重构类以使其适应特殊化(例如,通过封装另一个内部的模板类成员,以便专门化仅限于该类)?
答案 0 :(得分:3)
模板专门化是否有可能从A继承'(没有实际的C ++继承)成员,如a和getA()?
简答:不。
答案很长:不,A
是一个类模板,因此它不是继承成员(数据或函数)的东西。
而且,你要求的听起来像 - 我怎么能打败专业化的整个目的呢?。好吧,对于不依赖于模板参数的成员,从基类继承。这是更直接的方式,以及语言为您提供的内容。
你不能只是从类型中继承成员函数而不扩展该类型
有很多技术可以实现这个目的:直接继承,混合,继承自上述成语等。
所有这些都通过继承来撰写接口。我不明白为什么要妖魔化它。
答案 1 :(得分:1)
如果您不想要其他课程,那么您可以在以下方面进行欺骗:
template <class T>
class A {
public:
void f() { cout << "here" << endl; }
};
template <> class A<char> : private A<A<char> > {
public:
using A<A<char> >::f;
};
当然有人希望能够编写template <> class A<char> : private A<char>
并获得继承自通用案例的专门化,但这是不可能的,所以我使用了一种技巧来实现某种类型的通用案例(这里类似于CRTP,但可以使用任何其他类型。)
另一个技巧是使用第二种类型和默认值。
答案 2 :(得分:0)
我找到了一种方法:
#include <type_traits>
typedef void**const*const** dummy;
// Generic template
template <typename T1, typename T2 = dummy>
class A {
static_assert(std::is_same<T1,dummy>::value || std::is_same<T2,dummy>::value,
"too many template arguments for class template 'A'");
typedef typename std::conditional<std::is_same<T1,dummy>::value, T2, T1>::type T;
public:
int a;
T x;
int getA() {return a;}
};
// Specialization for int
template <typename X>
class A<int,X> : public A<X,int> {
public:
void foo() {}
};
类模板A仅使用一个模板参数实例化。当用int以外的任何类型实例化A时,它具有预期的泛型的所有成员。当用int实例化A时,它不仅具有专门化的成员,而且还具有泛型的成员。