Clang and GCC disagree on constructor choice when using shape binding and initializer_list
In my Qt5 project, I came across the following setup:
#include <initializer_list>
struct QJsonArray;
struct QJsonValue
{
/*explicit*/ QJsonValue(QJsonArray const &) {}
};
struct QJsonArray
{
QJsonArray(QJsonArray const &) {}
QJsonArray(std::initializer_list<QJsonValue>) {}
};
void f(QJsonArray a = {})
{
QJsonArray b {a}; // GCC: init-list ; Clang: Copy-Cc
QJsonArray c (a); // GCC: Copy-Cc ; Clang: Copy-Cc
}
int main()
{
f();
}
You can see that on the commented lines, GCC and Clang disagree on which constructor should be called.
(You can check this code on C ++ Compiler Explorer with latest GCC and Clang with flag -std=c++11
)
If I uncomment explicit
, both compilers choose the same constructor (copy constructor).
What's the compiler here?
source to share
GCC is correct here. For non-aggregates, using braced-init lists can bypass the copy constructors in favor of the appropriate constructor initializer_list
. Since it QJsonArray
can be implicitly converted to QJsonValue
, and QJsonArray
has a constructor initializer_list
that accepts QJsonValue
s, this constructor would be preferred over even the copy constructor.
source to share