C++20 中自动生成构造函数的新类型

Ziz*_*Tai 2 c++ c++20

下面的代码不能在 GCC 11 上编译-std=c++17,但可以-std=c++20

#include <iostream>
#include <string>

struct Foo {
    std::string s;
    int i;
};

int main()
{
    Foo foo("hello", 42);
    std::cout << foo.s << ' ' << foo.i << '\n';
}
Run Code Online (Sandbox Code Playgroud)

C++20 中的哪些功能可以实现此目的?编译器生成什么样的构造函数?

Ruk*_*uks 7

这里使用的 C++20 功能是从括号初始化聚合 (P0960R3)

本文建议允许从带括号的值列表初始化聚合;也就是说,Aggr(val1, val2)与 的含义相同Aggr{val1, val2},只是允许缩小转换。

这是上面链接中的示例:

struct A {
  int a;
  int&& r;
};

int f();
int n = 10;

A a1{1, f()};               // OK, lifetime is extended
A a2(1, f());               // well-formed, but dangling reference
A a3{1.0, 1};               // error: narrowing conversion
A a4(1.0, 1);               // well-formed, but dangling reference
A a5(1.0, std::move(n));    // OK
Run Code Online (Sandbox Code Playgroud)

因此,为了让您的代码能够使用 C++17,只需将括号替换为大括号即可。

#include <iostream>
#include <string>

struct Foo {
    std::string s;
    int i;
};

int main()
{
    Foo foo{"hello", 42};
    std::cout << foo.s << ' ' << foo.i << '\n';
}
Run Code Online (Sandbox Code Playgroud)

  • @Naaruto 如果您访问相同的链接,您会看到以下内容:“*通过大括号绑定到聚合的引用成员的临时变量的生命周期已延长*,而*当通过圆括号传递临时变量*时,不会发生任何扩展。” 因此,在“a2”和“a4”的情况下,临时对象被破坏,但引用仍然保持不变,但当它们引用已删除的对象时,它们就会变成“悬空”。 (2认同)