Constructor taking std::initializer_list is preferred over other constructors
Asked Answered
S

1

11

I compile this code below with GCC 11.1.0 with a flag -std=c++17. It occurs that on the stdout is printed initializer_list.

I compiled the same code with MSVC with the flag -std=c++17 but it printed "copy constructor". Which compiler is more compliant with the cpp standard? Is compiler free to choose one of the constructors?

#include <iostream>
using namespace std;

struct S
{
    S(int) { }
    S(initializer_list<int>) { cout << "initializer_list"; }
    S(const S&) { cout << "copy constructor"; }

    operator int() const { return 1; };
};

int main()
{
    S s1(20);
    S s2{ s1 };
}
Startle answered 10/7, 2021 at 14:51 Comment(0)
N
13

The compiler is pretty much never "free to choose" for stuff like this. If it were, we wouldn't be able to write pretty much any portable C++ code.

[over.match.list] does give priority to initializer_list constructors. Constructor function overloading under the rules of list initialization gets invoked at step 3.6. Steps 3.1-3.5 do not apply, as your type doesn't qualify for any of those cases. Step 3.1 is particularly interesting, as it is specifically meant to invoke copy constructors instead of doing other things, but it also only applies to aggregates. Which your type is not.

Since your type is implicitly convertible to int, and your type takes an initializer_list<int>, there is a valid way to build an initializer_list that matches a constructor for the type in question. Therefore, this is the constructor [over.match.list] will select.

So in this case, VC++ is wrong. As is Clang, apparently.

Natiha answered 10/7, 2021 at 15:22 Comment(3)
So in this case, VC++ is wrong. Is VC++ ever right in these language-lawyer debates?Shoulder
@SilvioMayolo: Pretty much anything surrounding coroutines will almost certainly be more accurate on VC++ than others.Natiha
@SilvioMayolo When gcc and clang are split, MSVC is sometimes right.Ohmmeter

© 2022 - 2024 — McMap. All rights reserved.