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