C ++ - 模板类专门化是否有一种方法可以包含通用模板中的代码?

时间:2017-11-17 23:08:21

标签: c++ templates template-specialization

给出一个C ++类:

template<typename T>
class A {
public:
    int a;
    T x;
    int getA() {return a;}
};

模板专门化是否有可能从A继承'(没有实际的C ++继承)成员,如a和getA()?此外,在编写为类执行大量模板特化的代码时,我应该多次键入相同的代码(这有点会破坏模板的整个目的),或重构类以使其适应特殊化(例如,通过封装另一个内部的模板类成员,以便专门化仅限于该类)?

3 个答案:

答案 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时,它不仅具有专门化的成员,而且还具有泛型的成员。