相互依赖的 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
我有两个 类,每个都可以从另一个构建。
示例:
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