The following example has been provided for aggregate initialization under Direct Initialization
struct A
{
explicit A(int i = 0) {}
};
A a[2](A(1)); // OK: initializes a[0] with A(1) and a[1] with A()
A b[2]{A(1)}; // error: implicit copy-list-initialization of b[1]
// from {} selected explicit constructor
The above code which has been OKed in the example doesn't compile for me:
main.cpp: In function ‘int main()’:
main.cpp:8:14: error: converting to ‘A’ from initializer list would use explicit constructor ‘A::A(int)’
8 | A a[2](A(1));
| ^
compilation terminated due to -Wfatal-errors.
The following is my complete source code based on the above example:
struct A
{
explicit A(int i = 0){}
};
int main (){
A a[2](A(1));
A b[2]{A(1)};
return 0;
}
The compilation command I am using is as shown below (compiler version is gcc 11.3.1):
g++ -ggdb -g3 -pedantic-errors -Wall -Wextra -Wfatal-errors -Wpedantic -std=c++20
Thoughts?
TIA
cppreference is correct, and GCC is wrong here. (But Clang gets it right. See Godbolt.) This initialization is governed by [dcl.init.general]/16.5:
There is no obstruction to value-initializing an object that has an explicit default constructor, except, as specified by [over.match.ctor]/1, when the initialization is "in the context of copy-initialization", which is not the case here, since the direct-initialization syntax was used.
However, when you use aggregate initialization syntax, then any elements that don't have a specified initializer are copy-initialized from
{}, so an explicit default constructor is not permitted to be selected in this context.