The code below doesn't compile on GCC 11 with -std=c 17
, but does with -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';
}
What's the feature in C 20 that enables this? What kind of constructor is generated by the compiler?
CodePudding user response:
The C 20 feature being used here is the initialization of aggregates from parenthesis (P0960R3):
This paper proposes allowing initializing aggregates from a parenthesized list of values; that is,
Aggr(val1, val2)
would mean the same thing asAggr{val1, val2}
, except that narrowing conversions are allowed.
Here is an example from the above link:
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
So, for your code to work with C 17, just replace the parenthesis with braces.
#include <iostream>
#include <string>
struct Foo {
std::string s;
int i;
};
int main()
{
Foo foo{"hello", 42};
std::cout << foo.s << ' ' << foo.i << '\n';
}