6

As far as I understand, the following program should work in C++20 mode:

#include <vector>

struct B{ int a0, a1; };

int main()
{
    std::vector<B> bs;
    bs.emplace_back( 0, 0 );
}

And it really does in Visual Studio 2019 and gcc 11. But not in clang 12, which produces the error:

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/alloc_traits.h:514:4: error: no matching function for call to 'construct_at'
          std::construct_at(__p, std::forward<_Args>(__args)...);
          ^~~~~~~~~~~~~~~~~

In online compiler: https://gcc.godbolt.org/z/GzccTWc5z

Is this because clang does not fully support C++20 yet?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Fedor
  • 17,146
  • 13
  • 40
  • 131

1 Answers1

9

This is a C++20 feature that allows aggregate initialization through the standard constructor syntax, rather than the typical braced-list initialization syntax. (Note that this only works if the parameters cannot be used in a valid call to a default or copy/move constructor. If they could, that would be called instead of performing aggregate initialization.)

According to the official C++ Support in Clang page, Clang does not yet support parenthesized initialization of aggregates (which is P0960R3 and P1975R0). This is as of Clang version 13.

A support matrix for C++20 features is also maintained on cppreference.com. This shows that support for P0960R3 is as follows:

  • GCC: supported as of version 10
  • MSVC: supported as of version 19.28
  • EDG eccp: supported as of version 5.1
  • Clang and Apple Clang: unsupported
  • Intel ICC: unsupported
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • 1
    "Note that this only works if the parameters cannot be used in a valid call to a default or copy/move constructor. If they could, that would be called instead of performing aggregate initialization.". At least that is consistent with brace-init which behaves in the same way AFAIK. Or is there a difference here? One thing comes to mind: I suspect if the initializer has an implicit conversion to the aggregate type, things could behave different. – Johannes Schaub - litb Jun 16 '21 at 17:20
  • Note that Clang 16 now supports it, but it's still unavailable on Apple clang. – WaterFox Dec 22 '22 at 23:45