This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-10-26


1673. Clarifying overload resolution for the second step of copy-initialization

Section: 12.2.4.2  [over.best.ics]     Status: C++14     Submitter: Vinny Romano     Date: 2013-04-29

N3690 comment CA 5

[Moved to DR at the February, 2014 meeting as part of document N3914.]

Currently, 12.2.4.2 [over.best.ics] paragraph 4 reads,

However, when considering the argument of a constructor or user-defined conversion function that is a candidate by 12.2.2.4 [over.match.ctor] when invoked for the copying/moving of the temporary in the second step of a class copy-initialization, by 12.2.2.8 [over.match.list] when passing the initializer list as a single argument or when the initializer list has exactly one element and a conversion to some class X or reference to (possibly cv-qualified) X is considered for the first parameter of a constructor of X, or by 12.2.2.5 [over.match.copy], 12.2.2.6 [over.match.conv], or 12.2.2.7 [over.match.ref] in all cases, only standard conversion sequences and ellipsis conversion sequences are considered.

This is cumbersome and hard to understand. A possible improvement might be:

However, only standard conversion sequences and ellipsis conversion sequences are considered if:

(Note that this rewording removes the restriction that applies during phase one of 12.2.2.8 [over.match.list], as there is no longer any way to trigger it due to the fact that only initializer-list constructors are candidates. See this bug report for details.)

Proposed resolution (September, 2013) [SUPERSEDED]:

Change 12.2.4.2 [over.best.ics] paragraph 4 as follows:

However, when considering the argument of a constructor or user-defined conversion function that is a candidate by 12.2.2.4 [over.match.ctor] when invoked for the copying/moving of the temporary in the second step of a class copy-initialization, by 12.2.2.8 [over.match.list] when passing the initializer list as a single argument or when the initializer list has exactly one element and a conversion to some class X or reference to (possibly cv-qualified) X is considered for the first parameter of a constructor of X, or by 12.2.2.5 [over.match.copy], 12.2.2.6 [over.match.conv], or 12.2.2.7 [over.match.ref] in all cases, only standard conversion sequences and ellipsis conversion sequences are considered. if the target is

and the constructor or user-defined conversion function is a candidate by

user-defined conversion sequences are not considered. [Example:

  struct X { X(); };
  struct B { operator X&(); };
  B b;
  X x({b}); // error: B::operator X&() is not a candidate

end example]

Additional note (October, 2013):

Questions have been raised about several of the bullets in the September, 2013 proposed resolution and whether a note would be preferable instead of or in addition to the example . The issue has been returned to "review" status to allow consideration of these questions.

Additional note (January, 2014):

It has also been observed that the proposed resolution would make the following example ill-formed by preventing the consideration of B's conversion function when initializing the first parameter of A's copy constructor:

  struct A {
    A() {}
    A(const A &) {}
  };

  struct B {
    operator A() { return A(); }
  } b;
  A a{b};