首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >覆盖模板方法

覆盖模板方法
EN

Stack Overflow用户
提问于 2014-12-16 13:33:39
回答 3查看 5.4K关注 0票数 2

我在试图覆盖一个模板方法。下面是一个很小的例子:

代码语言:javascript
复制
#include <iostream>

class Base
{
public:
    template <typename T>
    void print(T var)
    {
        std::cout << "This is a generic place holder!\n";
    }
};

class A: public Base
{
public:
    template <typename T>
    void print(T var)
    {
        std::cout << "This is A printing " << var << "\n";
    }
};

class B: public Base
{
public:
    template <typename T>
    void print(T var)
    {
        std::cout << "This is B printing " << var << "\n";
    }
};


int main()
{
    Base * base[2];
    base[1] = new A;
    base[2] = new B;

    base[1]->print(5);
    base[2]->print(5);

    delete base[1];
    delete base[2];
    return 0;
}

在这两种情况下,输出都是This is a generic place holder!,如何实现调用派生类的方法?

如果该方法不是模板,我可以定义它为virtual,它将按预期工作(已经尝试过了),但它需要是一个模板。那我做错什么了?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-12-16 13:41:04

首先,成员函数模板不能是虚拟的,派生类中的成员函数模板不能覆盖基类中的虚拟成员函数。

由于您的代码,指针的类型是Base*,因此在模板成员函数实例化中,Base中的函数被实例化,这就是为什么调用基函数的原因。

如果使用A*和B*,则将实例化和调用子节点中的函数。

票数 1
EN

Stack Overflow用户

发布于 2014-12-16 13:59:11

两个调用Base::print的原因与print是一个模板方法这一事实无关,与其是非虚拟的事实有关。不管print是什么,A::printB::print永远不会被考虑。

现在,实际通过一个A::print调用Base*的典型解决方案是简单地使print成为一个virtual方法。但是,由于print是一个模板,所以这是不可能的,而且您不能根据规则拥有模板虚拟方法。

其中一种方法就是类型擦除。您可以使用Boost.TypeErasure执行以下操作:

代码语言:javascript
复制
typedef any<mpl::vector<
    copy_constructible<>,
    typeid_<>,
    ostreamable<>
> > any_streamable;

struct Base {
    virtual void print(any_streamable var) // not a template!
    {
        std::cout << "This is a generic place holder!\n";
    }        
};

struct A : Base {
    void print(any_streamable var) {
        std::cout << "This is A printing " << var << "\n";
    }
};

对于简单的事情,比如流,您也可以自己编写,而不需要库。

票数 3
EN

Stack Overflow用户

发布于 2014-12-17 03:34:34

虽然非专用模板方法是虚拟的(例如,vtable是什么样子的)是没有意义的,但值得指出的是,模板方法的专门化不可能是虚拟的,并且允许它具有重大的好处。我将此提交给C++委员会,作为N3405的最后一节。到目前为止,委员会还没有考虑到这一点,但我甚至还有一些更老的文件需要考虑,所以仍然有希望:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27505871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档