Sir*_*r2B 6 c++ c++17 std-variant
我有一个类 C,其中包含一个 struct S 和一个 std::variant 作为成员。struct S 有一个 int 成员 a,初始化为 0。代码如下:
#include <variant>
class C
{
struct S {
int a = 0;
};
std::variant<S> test;
};
int main()
{
C ctest;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用 gcc 12.2.1(也使用不同的编译器)编译此代码时,出现以下错误:
#include <variant>
class C
{
struct S {
int a = 0;
};
std::variant<S> test;
};
int main()
{
C ctest;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处查看代码和错误消息: https: //onlinegdb.com/ZdfGp9avn
但是,如果我从结构 S 中删除默认赋值 =0,则代码编译时不会出现错误。为什么会发生这种情况?如何在不删除默认分配的情况下修复此错误?在这种情况下,有默认分配与没有默认分配有什么区别?
S在完整类上下文之前不可默认构造,因为非静态数据成员初始值设定项的定义尚不可用(仅成员的声明)。
这意味着当std::variant<S>尝试计算是否S默认可构造时,编译器拥有的只是struct S { int a = ???; }. 它不知道编译器生成的默认构造函数是否应该抛出,因为它不知道 的a初始化程序是否抛出。
修复方法是使用手动说明符指定它noexcept:
class C
{
struct S {
int a = 0;
S() noexcept = default;
// Or `S() noexcept(false) = default;` if it isn't noexcept
};
std::variant<S> test;
};
Run Code Online (Sandbox Code Playgroud)
或者将类型移出,以便在使用时完整:
struct S {
int a = 0;
};
class C {
using S = ::S;
std::variant<S> test;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |