有没有办法转发声明协方差? [英] Is there a way to forward declare covariance?

查看:133
本文介绍了有没有办法转发声明协方差?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这些抽象类 Foo Bar

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;
};

进一步假设我有派生类 ConcreteFoo ConcreteBar 。我想协同改进 foo() bar()方法的返回类型,如下所示:

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();
};

这不会编译,因为我们亲爱的单遍编译器不知道 ConcreteBar 将继承 Bar ,因此 ConcreteBar 是一个完全合法的协变返回类型。 Plain forward声明 ConcreteBar 也不工作,因为它不告诉编译器关于继承的任何事情。

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.

这个C ++的许多缺点之一将不得不与这个困境一起生活或者真的有办法解决这个困境吗?

Is this one of the many shortcomings of C++ I'll have to live with or is there actually a way around this dilemma?

推荐答案

你可以很容易地伪造它,但是你失去了静态类型检查。如果你用 dynamic_casts 替换 static_casts ,你有编译器在内部使用的,但你没有动态或静态类型检查:

You can fake it quite easily, but you lose the static type checking. If you replace the dynamic_casts by static_casts, you have what the compiler is using internally, but you have no dynamic nor static type check:

class Foo;
class Bar;

class Foo
{
public:
  Bar* bar();
protected:
  virtual Bar* doBar();
};

class Bar;
{
public:
  Foo* foo();
public:
  virtual Foo* doFoo();
};

inline Bar* Foo::bar() { return doBar(); }
inline Foo* Bar::foo() { return doFoo(); }

class ConcreteFoo;
class ConcreteBar;
class ConcreteFoo : public Foo
{
public:
  ConcreteBar* bar();
protected:
  Bar* doBar();
};

class ConcreteBar : public Bar
{
public:
   ConcreteFoo* foo();
public:
   Foo* doFoo();
};

inline ConcreteBar* ConcreteFoo::bar() { return &dynamic_cast<ConcreteBar&>(*doBar()); }
inline ConcreteFoo* ConcreteBar::foo() { return &dynamic_cast<ConcreteFoo&>(*doFoo()); }

这篇关于有没有办法转发声明协方差?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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