Title
Clarifying overload resolution for the second step of copy-initialization
Status
c++14
Section
12.2.4.2 [over.best.ics]
Submitter
Vinny Romano

Created on 2013-04-29.00:00:00 last changed 121 months ago

Messages

Date: 2014-02-15.00:00:00

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

Date: 2014-01-15.00:00:00

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};
Date: 2013-10-15.00:00:00

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.

Date: 2013-09-15.00:00:00

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

  • the first parameter of a constructor of a class X or

  • the implicit object parameter of a user-defined conversion function,

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

  • 12.2.2.4 [over.match.ctor], when the argument is the temporary acting as the source in the second step of a class copy-initialization,

  • 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), or

  • the second phase of 12.2.2.8 [over.match.list] when the initializer list has exactly one element, and the conversion is to X or reference to (possibly cv-qualified) X,

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]

Date: 2013-10-14.00:00:00
N3690 comment CA 5

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:

  • the parameter is the first parameter of a constructor of a class X, or

  • the parameter is the implicit object parameter of a user-defined conversion function, and

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

  • 12.2.2.4 [over.match.ctor] — when the argument is the temporary being copied/moved in the second step of a class copy-initialization.

    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.

    12.2.2.8 [over.match.list] — during phase two, when the argument was the only element in the initializer list, and the parameter is of type X or reference to (possibly cv-qualified) X.

(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.)

History
Date User Action Args
2014-11-24 00:00:00adminsetstatus: dr -> c++14
2014-03-03 00:00:00adminsetmessages: + msg4963
2014-03-03 00:00:00adminsetstatus: review -> dr
2014-01-20 00:00:00adminsetmessages: + msg4744
2013-10-14 00:00:00adminsetmessages: + msg4612
2013-10-14 00:00:00adminsetmessages: + msg4611
2013-10-14 00:00:00adminsetstatus: open -> review
2013-04-29 00:00:00admincreate