Hiya,
When initialising class members with braces, it seems Clang doesn’t have the same behaviour as GCC/MSVC. GCC and MSVC try to use the initializer-list-constructor if defined, where Clang appears to be using the copy-constructor.
My guess is that copy elision is what might be causing this behaviour. Is it correct, or is this a bug?
For the way I’m using it, the initializer-list-constructor behaves quite differently to the copy-constructor and triggered completely different behaviour between Clang and the other compilers.
Super keen to hear any thoughts.
Cheers,
Matt
Repro case:
struct ContainedObj {
ContainedObj() = default;
ContainedObj(ContainedObj const& other) { std::cout << this << “: copy ctor” << std::endl; }
ContainedObj(std::initializer_list) { std::cout << this << “: il ctor” << std::endl; }
};
struct WithBraces {
ContainedObj mContained;
explicit WithBraces(ContainedObj const& contained) : mContained{contained} {}
};
struct WithBrackets {
ContainedObj mContained;
explicit WithBrackets(ContainedObj const& contained) : mContained(contained) {}
};
ContainedObj a;
WithBrackets b(a);
WithBrackets c{a};
WithBraces d(a);
WithBraces e{a};
Output on MSVC 2017 and g++ 6.3.0:
00F3FA6B: copy ctor
00F3FA5F: copy ctor
00F3F887: copy ctor
00F3FAF3: il ctor
00F3F887: copy ctor
00F3FA47: il ctor
Clang output:
0x7ffeefbff580: copy ctor
0x7ffeefbff578: copy ctor
0x7ffeefbff570: copy ctor
0x7ffeefbff568: copy ctor