模板特化和继承
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>();
;
然后您可以为每种类型单独专门化每个函数,或者根据需要专门化整个类型。
【讨论】:
以上是关于模板特化和继承的主要内容,如果未能解决你的问题,请参考以下文章