我希望能够做到这样的事情:
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);
有没有办法在我当前的设置中执行此操作,或者我是否需要编写&#34; master&#34; class是为了继承Foo()
?
答案 0 :(得分:1)
您可以重复专业化中的公共部分
template<typename T>
class myClass
{
public:
double Foo(double x){return x;}
};
template<>
class myClass<SpecialType>
{
public:
double Foo(double x){return x;}
double Bar(double x){return x + 1.0;}
};
或使用其他助手类:
template<typename T> struct BarHelper<T> {};
template<> struct BarHelper<SpecialType>
{
double Bar(double x) {return x + 1.0;}
};
template<typename T>
class myClass : public BarHelper<T>
{
public:
double Foo(double x){return x;}
// inherit Bar method for SpecialType.
};
答案 1 :(得分:1)
两个选项(多个选项):
构造一个公共基类,在其中放置所有与类型无关的东西(推荐):
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;}
}
特别是当您的功能不依赖于模板参数时,建议使用此功能。
从您的非专业课程中导出:
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)
上的重载已足够,请忘记整个模板内容并使用第一个替代方案。