相互依赖的constexpr构造函数

发布于 2025-01-24 00:06:04 字数 563 浏览 0 评论 0原文

我有两个类,每个类都可以彼此构造。

示例:

class B;

class A{
 public:
  double val;
  constexpr A(B b): val(b.val){};
};

class B{
 public:
  double val;
  constexpr B(A a): val(a.val){};
};

我需要转发declare b类,所以一个知道它。当这些构造函数不是constexpr时,我可以将它们的定义移至源文件中,并愉快地编译。

但是,要使它成为constexpr,必须在标题中定义它们。 b可以从a构造,因为它看到了a的完整定义。 a无法从b构造,因为它只会看到声明,因此对b :: val一无所知。

我只剩下类B constexpr。是否有两种课程的方法?

I have two classes, each constructible from the other.

Example:

class B;

class A{
 public:
  double val;
  constexpr A(B b): val(b.val){};
};

class B{
 public:
  double val;
  constexpr B(A a): val(a.val){};
};

I need to forward-declare class B, so A knows about it. When these constructors are not constexpr, I can move their definitions to a source file and it happily compiles.

However, to make it constexpr, they have to be defined in the header. B is ok to construct from A, because it sees the full definition of A. A cannot construct from B because it only sees a declaration, and therefore has no idea about B::val.

I'm left with only making class B constexpr. Is there a way to do it for both classes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌伤浅笑 2025-01-31 00:06:04

使用GCC我会得到错误( https://godbolt.org/z/qvp7absdr

<source>:6:15: error: 'b' has incomplete type
    6 | constexpr A(B b) : val(b.val){};
      |             ~~^
<source>:1:7: note: forward declaration of 'class B'
    1 | class B;
      |       ^
<source>: In constructor 'constexpr A::A(B)':
<source>:6:11: error: invalid type for parameter 1 of 'constexpr' function 'constexpr A::A(B)'
    6 | constexpr A(B b) : val(b.val){};
      |           ^
Compiler returned: 1

)失败是因为类型b在使用时是不完整的,这是构造函数a :: a(b b)的定义。

为了处理此问题,我们可以等到我们声明b才能完全定义构造函数并使用B。从本质上讲,将构造函数的定义移出类a课堂后b

class B;

class A{
 public:
  double val;
  constexpr A(B b);
};

class B{
 public:
  double val;
  constexpr B(A a): val(a.val){};
};

constexpr A::A(B b) : val(b.val){};

请参阅没有汇编问题的示例:
https://godbolt.org/z/4444fbcr8sh

Using gcc I get the error (https://godbolt.org/z/qvP7absdr):

<source>:6:15: error: 'b' has incomplete type
    6 | constexpr A(B b) : val(b.val){};
      |             ~~^
<source>:1:7: note: forward declaration of 'class B'
    1 | class B;
      |       ^
<source>: In constructor 'constexpr A::A(B)':
<source>:6:11: error: invalid type for parameter 1 of 'constexpr' function 'constexpr A::A(B)'
    6 | constexpr A(B b) : val(b.val){};
      |           ^
Compiler returned: 1

So this fails because type B is incomplete when it is used it is the definition of the constructor A::A(B b).

In order to deal with this we can wait until we have declared B fully before we define the constructor and use B. Essentially, move the definition of the constructor out of class A and after class B

class B;

class A{
 public:
  double val;
  constexpr A(B b);
};

class B{
 public:
  double val;
  constexpr B(A a): val(a.val){};
};

constexpr A::A(B b) : val(b.val){};

See an example without compilations issues:
https://godbolt.org/z/44fbcr8sh

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文