c++ - 专门化模板类时的继承

标签 c++ templates

我希望能够做这样的事情:

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/

相关文章:

c++ - 使用 C++ 的解释器和编译器的好书?

c++ - 如果智能指针持有的对象在别处被删除会发生什么?

c++ - C++中干净高效的字符串连接

c++ - 奇怪的预处理

javascript - 如何计算并显示每个树表分支的内部元素数量?

c++ - 为什么我不能对提取运算符执行 decltype

java - Freemarker 循环似乎没有按顺序打印

c++ - 使用 boost.python 导出 C++ 多态函数的聪明方法

c++ - 通过模板函数 C++ 的引用传递

c++ - 如何通过复制和引用将 vector 传递给函数?