Clang & GCC are right, MSVC has a bug
This is CWG 1589:
1589. Ambiguous ranking of list-initialization sequences
Section: 16.3.3.2 [over.ics.rank]
Status: CD4
Submitter: Johannes Schaub
Date: 2012-11-21
[Moved to DR at the November, 2014 meeting.]
The interpretation of the following example is unclear in the current
wording:
void f(long);
void f(initializer_list<int>);
int main() { f({1L});
The problem is that a list-initialization sequence can also be a
standard conversion sequence, depending on the types of the elements
and the type of the parameter, so more than one bullet in the list
in 16.3.3.2 [over.ics.rank] paragraph 3 applies:
[...]
These bullets give opposite results for the example above, and there
is implementation variance in which is selected.
[...]
Proposed resolution (June, 2014):
This issue is resolved by the resolution of issue
1467.
Which as per the resolution was resolved via CWG 1467:
1467. List-initialization of aggregate from same-type object
[...]
Proposed resolution (June, 2014):
[...]
- Move the final bullet of 16.3.3.2 [over.ics.rank] paragraph 3 to the beginning of the list and change it as follows:
[...]
even if one of the other rules in this paragraph would otherwise apply. [Example: ... — end example]
This resolution also resolves issues 1490, 1589, 1631, 1756, and 1758.
Particularly by re-ording the [over.ics.rank]/3 such that [over.ics.rank]/3.1 now applies for the OP's case, and takes precedence over the other rules of [over.ics.rank]/3:
List-initialization sequence L1
is a better conversion sequence than
list-initialization sequence L2
if
- (3.1.1)
L1
converts to std::initializer_list<X>
for some X
and L2
does not, or, if not that
- (3.1.2) [...]
even if one of the other rules in this paragraph would otherwise apply.
Compilers such as GCC and Clang has since back-ported DR 1467 to earlier standards (C++11 and C++14); Clang specifically as of Clang 3.7, and we can verify the CWG 1589 connection to OP's example as it is rejected by Clang 3.6 but accepted by Clang 3.7 (DEMO).
MSVC, on the other, has seemingly has not implemented this change even as per the updated C++17 standard where it is no longer "just a" DR.
std::initializer_list
. – Thymusstd::initializer_list
is changed toint
, then MSVC agrees with GCC. – BussyA(A{0})
). – Jettiejettison