相互依赖的 constexpr 构造函数

Mutually dependent constexpr constructors

我有两个 类,每个都可以从另一个构建。

示例:

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

我需要forward-declareclass B,所以A知道了。当这些构造函数不是 constexpr 时,我可以将它们的定义移动到一个源文件中,它可以愉快地编译。

然而,要使其成为constexpr,它们必须在header中定义。 B 可以从 A 构造,因为它看到了 A 的完整定义。 A 不能从 B 构造,因为它只看到一个声明,因此不知道 B::val.

我只剩下 class B constexpr。 类 有没有办法做到这一点?

使用 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。本质上,将构造函数的定义移出class A 之后 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){};

查看没有编译问题的示例: https://godbolt.org/z/44fbcr8sh