为什么不允许这种部分填充模板和接口的组合?

时间:2017-05-10 20:10:49

标签: c++

我有一个模板类我尝试部分填充功能以提供更高级别的库。模板类有接口。

我遇到了一个问题。当我尝试编译以下示例代码来演示问题时,我得到:

C2555   'concreter<int>::tuberMaker::makePotato': overriding virtual function return type differs and is not covariant from 'abstracter<int,U>::potatoMaker::makePotato'

然而,这没有任何意义,因为块茎应该与马铃薯协变 - 它明确地继承了马铃薯!为什么我不能在这里使用块茎工厂?有一个很好的解决方法吗?

template <typename T,typename U>
class abstracter{
public:
    class potato
    {
    public:
        virtual void doSomething()=0;
    };
    class potatoMaker
    {
    public:
        virtual std::shared_ptr<potato> makePotato()=0;
    };
};

template <typename U>
class concreter
{
public:
    class tuber : public abstracter<int,U>::potato
    {
    public:
        void doSomething()
        {
            std::cout << "Something" << std::endl;
        }
    };
    class tuberMaker : public abstracter<int,U>::potatoMaker
    {
    public:
        std::shared_ptr<tuber> makePotato()
        {
            return std::make_shared<tuber>();
        }
    };
};

int main()
{
    concreter<int>::tuberMaker z = concreter<int>::tuberMaker();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

因为虚方法不能返回不同的类型?为什么你需要它,你需要的只是一个使用类型擦除的工厂方法。

    class tuberMaker : public abstracter<int,U>::potatoMaker
    {
    public:
        std::shared_ptr<typename abstracter<int,U>::potato> makePotato()
        {
            return std::make_shared<tuber>();
        }
    };

当然,假设块茎是马铃薯的后代(或儿童......或子类...无论你想称它为什么)。使用看起来更容易理解的原始指针:

        potato* makePotato()
        {
            return new tuber();
        }