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?

+3


source to share


1 answer


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.



+4


source







All Articles