我希望能够做这样的事情:
template<typename T>
class myClass{
public:
double Foo(double x){return x;}
}
template<>
class myClass<SpecialType>{
public:
double Bar(double x){return x+1.0;}
}
现在,我想实例化特化,但仍然可以访问方法 Foo
,而无需重写特化中的整个内容,即:
myClass<SpecialType> A;
double y = A.Foo(1.0);
有没有办法用我当前的设置来做到这一点,或者我是否需要编写一个“主”类才能继承 Foo()
?
最佳答案
两个选项(更多):
构造一个公共(public)基类,在其中放置所有与类型无关的内容(推荐):
struct myClassBase { virtual double Foo(double x) const {return x+1.0;} }; template<typename T> struct myClass : public myClassBase { //... }; template<> struct myClass<SpecialType> : public myClassBase { double Bar(double x){return x+1.0;} }
特别是当您的函数不依赖于模板参数时,建议这样做。
源自您的非专业类(class):
template<> struct myClass<SpecialType> : public myClass</* be careful what to write here */> { double Bar(double x){return x+1.0;} }
不过,您必须小心,将哪种类型传递给非专用类模板(特别是当您的成员函数依赖于模板类型时——它们应该以某种方式有意义)。
另一个更静态的选项是应用 strategy pattern :将所有功能转移到一些小的策略类中,然后通过组合这些类来构建所需的类(缺点:您必须再次公开功能),或者通过多重继承(这里您不必重述整个事情,但要小心)再次避免歧义)。
编辑:根据您的评论,以下是完成同一任务的 CRTP 方法:
template<typename Derived>
struct myClassBase
{
double Foo(double x) const
{
return static_cast<Derived const&>(*this).specialMember(x);
}
//all other stuff independent of the derived class specialization
//possibly define specialMember once:
virtual double specialMember(double x) const { return x; }
}
template<typename T> struct myClass : public myClassBase<myClass<T> >
{
//... special member of Base class is sufficient
};
template<> struct myClass<SpecialType> : public myClassBase<myClass<SpecialType> >
{
virtual double specialMember(double x) const { return x+1.0; }
};
再次注意,只有当模板类型真正参与函数的评估时,这才有意义。
另一方面,如果重载 double Foo(double x)
就足够了,请忘记整个模板内容并使用第一个替代方案。
关于c++ - 专门化模板类时的继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30458431/