有没有办法转发声明协方差?
假设我有这些抽象类 Foo
和 Bar
:
class Foo;
class Bar;
class Foo
{
public:
virtual Bar* bar() = 0;
};
class Bar
{
public:
virtual Foo* foo() = 0;
};
进一步假设我有派生类 ConcreteFoo
和 ConcreteBar
。 我想协变地改进 foo()
和 bar()
方法的返回类型,如下所示:
class ConcreteFoo : public Foo
{
public:
ConcreteBar* bar();
};
class ConcreteBar : public Bar
{
public:
ConcreteFoo* foo();
};
这不会编译,因为我们心爱的单通道编译器不知道ConcreteBar
将从 Bar
继承,因此 ConcreteBar
是一个完全合法的协变返回类型。 简单的前向声明 ConcreteBar
也不起作用,因为它不会告诉编译器有关继承的任何信息。
这是我必须忍受的 C++ 的缺点吗?或者实际上有办法解决这个困境吗?
Suppose I have these abstract classes Foo
and Bar
:
class Foo;
class Bar;
class Foo
{
public:
virtual Bar* bar() = 0;
};
class Bar
{
public:
virtual Foo* foo() = 0;
};
Suppose further that I have the derived class ConcreteFoo
and ConcreteBar
. I want to covariantly refine the return type of the foo()
and bar()
methods like this:
class ConcreteFoo : public Foo
{
public:
ConcreteBar* bar();
};
class ConcreteBar : public Bar
{
public:
ConcreteFoo* foo();
};
This won't compile since our beloved single pass compiler does not know that ConcreteBar
will inherit from Bar
, and so that ConcreteBar
is a perfectly legal covariant return type. Plain forward declaring ConcreteBar
does not work, either, since it does not tell the compiler anything about inheritance.
Is this a shortcoming of C++ I'll have to live with or is there actually a way around this dilemma?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
协方差基于继承图,因此由于您无法声明,
因此无法告诉编译器有关协方差的信息。
但是你可以在模板的帮助下做到这一点,将 ConcretFoo::bar 声明为模板,稍后的边界可以解决这个问题
Covariance is based on inheritance diagram, so since you cannot declare
hence no way to tell compiler about covariance.
But you can do it with help of templates, declare ConcretFoo::bar as template and later bounding allows you solve this problem
这个怎么样。
How about this.
静态多态不能解决你的问题吗?
通过模板参数向基类提供派生类?
那么基类将知道派生类型并声明一个适当的虚拟?
Doesn't static polymorphism solve your problem?
Feeding the base class with the derived class through template argument?
So the base class will know the derivative Type and declare a proper virtual?
你可以很容易地伪造它,但你会失去静态类型检查。 如果将
dynamic_casts
替换为static_casts
,则您拥有编译器内部使用的内容,但没有动态或静态类型检查:You can fake it quite easily, but you lose the static type checking. If you replace the
dynamic_casts
bystatic_casts
, you have what the compiler is using internally, but you have no dynamic nor static type check: