“无效的协变量返回类型"方法返回基于模板的对象的嵌套类中的错误 [英] "Invalid covariant return type" errors in nested classes with methods returning template-based objects

查看:148
本文介绍了“无效的协变量返回类型"方法返回基于模板的对象的嵌套类中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下C ++代码在编译时给了我这些错误:

The following C++ code gives me these errors when compiled:

covariant.cpp:32:22: error: invalid covariant return type for ‘virtual Q<B> C::test()’
covariant.cpp:22:22: error:   overriding ‘virtual Q<A> B::test()’

我不想将行virtual Q<B> test() {}更改为virtual Q<A> test() {},尽管它消除了编译错误.还有另一种解决此问题的方法吗?

I do not want to change the line virtual Q<B> test() {} to virtual Q<A> test() {} although it removes the compilation errors. Is there another way to solve this problem?

template <class T>
class Q
{
    public:
        Q() {}
        virtual ~Q() {}
};

class A
{
    public:
        A() {}
        virtual ~A() {}    
};

class B
{
    public:
        B() {}
        virtual ~B() {}

        virtual Q<A> test() = 0;

};

class C : public B
{
    public:
        C() {}
        virtual ~C() {}

        virtual Q<B> test() {}
};

推荐答案

Q<B>Q<A>是不相关的类.假设您是B呼叫test()的客户:如果不知道结果的类型,将结果分配给什么?

Q<B> and Q<A> are unrelated classes. Imagine you are a client of B calling test(): what do you assign the result to, if you do not know what type it is going to have?

Q<A>Q<B>都是同一类模板的实例这一事实并没有改变它们是两个完全不相关的类,可能具有完全不同的布局的事实(由于模板专门化).

The fact that both Q<A> and Q<B> are instances of the same class template does not change the fact that they are two completely unrelated classes, possibly with a completely different layout (due to template specialization).

这与这样做没有什么不同

This would not be any different from doing:

struct X
{
    virtual std::string test() = 0;
};

struct Y : X
{
    virtual int test() { return 42; } // ERROR! std::string and int are
                                      // unrelated, just as Q<A> and Q<B>
};

在指向X的指针上调用test()的客户端将期望结果为string,但是哇!",该指针所指向的对象的类型为Y,并且返回Y::test()的类型是int.应该怎么办?运行时崩溃?

The client calling test() on a pointer to X would expect the result to be a string, but "Whoops!", the object pointed to by that pointer is of type Y, and the return type of Y::test() is int. What should happen? A run-time crash?

Y y;
X* p = &y;
std::string s = p->test(); // D'OH!

C ++是一种静态类型的语言,这意味着类型检查是在编译时执行的.在这种情况下,来自编译器的消息会告诉您派生类不遵循其派生类的接口.

C++ is a statically typed language, meaning that type checking is performed at compile-time. In this case, the message from the compiler is there to tell you that the derived class does not adhere to the interface of the class it derives from.

如果您想知道"无效的协变量返回类型"是什么意思,尤其是单词"协变量",就很容易解释了.

If you are wondering what "invalid covariant return type" means, and in particular the word "covariant", that's easily explained.

假设您有一个带有虚拟函数foo()并返回X*的基类B:

Suppose you have a base class B with a virtual function foo() that returns an X*:

struct B
{
    virtual X* foo();
};

并假设您有一个从B派生的类D通过返回一个Y*覆盖了foo(),其中Y是从X派生的类:

And suppose that you have a class D derived from B that overrides foo() by returning an Y*, where Y is a class derived from X:

struct D : B
{
    virtual Y* foo();
};

这是问题吗?好吧,正确的答案来自于回答了这个稍微好一点的问题:"对于调用foo()的客户来说,希望返回X*的客户会遇到问题吗?"

Is this a problem? Well, the right answer comes from answering this slightly better question: "Would that be a problem for a client calling foo() that expects an X* to be returned?"

该问题的答案显然是否",因为YX的派生类,因此您可以返回指向Y的指针,而不是指向X的指针:

And the answer to that question is obviously "No", since Y is a derived class of X, so you can return a pointer to Y instead of a pointer to X:

D d;
B* b = &d;
X* p = b->foo(); // Returns an Y*, but that's OK, because a pointer to Y can be
                 // assigned to a pointer to X

这是协变返回类型的示例.在您的示例中,C::test()的返回类型与B::test()的返回类型不协变.

This is an example of a covariant return type. In your example, the return type of C::test() is not covariant with respect to the return type of B::test().

这篇关于“无效的协变量返回类型"方法返回基于模板的对象的嵌套类中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆