With P0960 "Allow initializing aggregates from a parenthesized list of values", you can do aggregates init with ()
s also.
However, this initialization allows narrowing while {}
s doesn't.
#include <vector>
#include <climits>
struct Foo
{
int x, y;
};
int main()
{
// auto p = new Foo{INT_MAX, UINT_MAX}; // still won't compile
auto q = new Foo(INT_MAX, UINT_MAX); // c++20 allows narrowing aggregates init
std::vector<Foo> v;
// v.emplace_back(Foo{INT_MAX, UINT_MAX}); // still won't compile
v.emplace_back(INT_MAX, UINT_MAX); // c++20 allows narrowing aggregates init
// in furtherly perfect forwardings
}
Is it possible to detect narrowing conversion with C++20 aggregate initialization with parentheses?
Paren-initializing aggregates permits narrowing conversions.
Constructors and aggregate-initialization behave differently, and the feature looks like a constructor invocation and so it is intentionally designed to behave like a constructor invocation as much as possible. All of the notable features of aggregate-initialization (narrowing converisons, lifetime extension for references, etc.) very intentionally do not exist int he paren-initialization case.
The only difference is that paren-initializing aggregates does evaluate the expressions left-to-right (whereas with a constructor call, we have indeterminate evaluation of arguments).
Specifically:
auto q = new Foo(INT_MAX, UINT_MAX);
will behave mostly as if you had actually written this constructor:
struct Foo
{
Foo(int x, int y) : x(x), y(y) { } // ~ish
int x, y;
};
Which itself does not warn on any compiler I tried today.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With