mardi 5 janvier 2016

Calling an explicit constructor with a braced-init list: ambiguous or not?

Consider the following:

struct A {
    A(int, int) { }
};

struct B {
    B(A ) { }                   // (1)
    explicit B(int, int ) { }   // (2)
};

int main() {
    B paren({1, 2});   // (3)
    B brace{1, 2};     // (4)
}

The construction of brace in (4) clearly and unambiguously calls (2). On clang, the construction of paren in (3) unambiguously calls (1) where as on gcc 5.2, it fails to compile with:

main.cpp: In function 'int main()':
main.cpp:11:19: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous
     B paren({1, 2});
                   ^
main.cpp:6:5: note: candidate: B::B(A)
     B(A ) { }  
     ^
main.cpp:5:8: note: candidate: constexpr B::B(const B&)
 struct B {
        ^
main.cpp:5:8: note: candidate: constexpr B::B(B&&)

Which compiler is right? I suspect clang is correct here, as the ambiguity in gcc can only arise through a path that involves implicitly constructing B{1,2} and passing that to the copy/move constructor - yet that constructor is marked explicit, so such implicit construction should not be allowed.

Aucun commentaire:

Enregistrer un commentaire