模板特化和继承

Posted

技术标签:

【中文标题】模板特化和继承【英文标题】:Template specialization and inheritance 【发布时间】:2013-06-08 00:56:01 【问题描述】:

假设我有一个包含很多函数的模板类,我想对它们进行专门化,只更改其中的一部分,而让其他的完全按照基本模板类中的规定进行。

我该怎么做?

以下是我想要实现的目标,但解决方案并不好,因为它不允许我将 int 的专业化称为 Base<int> - 我需要为此使用 IntSpec

#include <iostream>

using namespace std;

template<typename T>
struct Base

  void print1() cout << "Base::print1" << endl;;
  void print2() cout << "Base::print2" << endl;;
;

struct IntSpec : public Base<int>

  void print2() cout << "Base<int>::print2()" << endl;;
;

int main()

  Base<double> d;
  // Base<int> i;  <-- I want this kind of instantiation
  IntSpec i;

  d.print1();
  d.print2();
  i.print1();
  i.print2();

输出是:

Base::print1
Base::print2
Base::print1
Base<int>::print2()

【问题讨论】:

【参考方案1】:

Nicol 的解决方案效果很好,但这是另一种选择:

template<typename T>
struct Base

  void print1() cout << "Base::print1" << endl;;
  void print2() cout << "Base::print2" << endl;;
;

template<>
void Base<int>::print2() cout << "Base<int>::print2()" << endl;;

这样您就可以只专门化特定的成员函数,并且仍然可以毫无问题地使用那些您没有专门化的成员函数(在这种情况下,print1)。所以现在你可以随心所欲地使用它了:

Base<int> i;
i.print1();
i.print2(); // calls your specialization

演示here.

【讨论】:

你确定这是标准 C++ 还是编译器扩展? @NicolBolas 我自己一直认为这是完全有效的(并且想知道为什么它不是马上的最佳答案),但这并不意味着什么(不过,我想记住曾经在 Vandevoorde-Josuttis 中明确搜索过,并找到了它)。 @NicolBolas 我相信§14.7.3/14 允许这样做。我错了吗?【参考方案2】:

你只需要使用两个模板类:

template<typename T>
struct CommonBase

  void print1() cout << "Base::print1" << endl;;
  void print2() cout << "Base::print2" << endl;;
;

template<typename T>
struct Base : public CommonBase<T>

;

template<>
struct Base<int> : public CommonBase<int>

  void print2() cout << "Base::print2" << endl;;
;

你总是使用Base,而不是CommonBase

【讨论】:

【参考方案3】:

另一种解决方案是在要重新定义的函数中添加一个间接级别,即

template<typename T>
struct foo

    template<typename T2>
    void bar_impl()
    
        //generic function
    

    void bar()
    
        bar_impl<T>();
    
;

然后您可以为每种类型单独专门化每个函数,或者根据需要专门化整个类型。

【讨论】:

以上是关于模板特化和继承的主要内容,如果未能解决你的问题,请参考以下文章

模板特化和模板模板参数的问题

联合作为模板化基类的部分特化

为啥可变参数模板的模板特化与非可变模板的特化不同?

C++模板进阶(非类型模板参数类模板的特化和模板的分离编译)

模板的全特化与偏特化

模板的特化