Title
Overload resolution based on size of array initializer-list
Status
c++14
Section
12.2.4.2.6 [over.ics.list]
Submitter
Johannes Schaub

Created on 2011-04-30.00:00:00 last changed 121 months ago

Messages

Date: 2013-09-15.00:00:00

[Moved to DR at the September, 2013 meeting.]

Date: 2022-11-20.07:54:16

Proposed resolution, April, 2013:

  1. Change 12.2.4.2.6 [over.ics.list] paragraph 2 as follows, adding a new paragraph (and moving the footnote to the new paragraph, as indicated):

  2. If the parameter type is std::initializer_list<X> or “array of X” [Footnote: Since there are no parameters of array type, this will only occur as the underlying type of a reference parameter. —end footnote] and all the elements of the initializer list can be implicitly converted to X, the implicit conversion sequence is the worst conversion necessary to convert an element of the list to X. This conversion can be a user-defined conversion even in the context of a call to an initializer-list constructor. [Example: ... —end example]

    Otherwise, if the parameter type is “array of N X” [Footnote: Since there are no parameters of array type, this will only occur as the underlying type of a reference parameter. —end footnote], if the initializer list has exactly N elements or if it has fewer than N elements and X is default-constructible, and if all the elements of the initializer list can be implicitly converted to X, the implicit conversion sequence is the worst conversion necessary to convert an element of the list to X.

    [Drafting note: no other case in the remainder of the paragraph applies when the initializer list has more elements than the parameter array.]
  3. Change 12.2.4.3 [over.ics.rank] paragraph 3 as follows:

  4. Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:

    • ...

    • List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if L1 converts to std::initializer_list<X> for some X and L2 does not.

      • L1 converts to std::initializer_list<X> for some X and L2 does not, or, if not that,

      • L1 converts to type “array of N1 T,” L2 converts to type “array of N2 T”, and N1 is smaller than N2.

Date: 2012-10-15.00:00:00

Notes from the October, 2012 meeting:

CWG determined that this issue is unrelated to array temporaries and that a tiebreaker should be added for this case in overload resolution.

Date: 2011-08-15.00:00:00

Rationale (August, 2011):

The implications of array temporaries for the language should be considered by the Evolution Working Group in a comprehensive fashion rather than on a case-by-case basis. See also issues 1300, 1326, and 1525.

Date: 2022-11-20.07:54:16

In an example like

  void f(int const(&)[2]);
  void f(int const(&)[3]);

  int main() {
   f({1, 2, 3});
  }

the current overload resolution rules make no provision for different array sizes and thus treats the call as ambiguous, even though it seems obvious that the second f should be chosen in this case.

History
Date User Action Args
2014-11-24 00:00:00adminsetstatus: drwp -> c++14
2014-03-03 00:00:00adminsetstatus: dr -> drwp
2013-10-14 00:00:00adminsetmessages: + msg4698
2013-10-14 00:00:00adminsetstatus: ready -> dr
2013-05-03 00:00:00adminsetmessages: + msg4315
2013-05-03 00:00:00adminsetstatus: drafting -> ready
2012-11-03 00:00:00adminsetmessages: + msg4102
2012-11-03 00:00:00adminsetstatus: extension -> drafting
2012-09-24 00:00:00adminsetmessages: + msg4039
2011-04-30 00:00:00admincreate