This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
[Moved to DR at the April, 2013 meeting.]
According to 12.2.4.2.6 [over.ics.list] paragraph 6, when passing an initializer-list argument to a non-class parameter,
if the initializer list has no elements, the implicit conversion sequence is the identity conversion.
However, there is no similar provision for an empty initializer list passed to a specialization of std::initializer_list or an array, as described in paragraph 2:
If the parameter type is std::initializer_list<X> or “array of X”134 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.
It is not clear what the result should be for a list with no elements. For example, given
void f(int) { printf("int\n"); } void f(std::initializer_list<int>) { printf("init list\n"); } int main() { f({}); }
current implementations result in init list being printed, presumably on the basis of the last bullet of 12.2.4.3 [over.ics.rank] paragraph 3:
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.
That would imply that both conversion sequences are the identity conversion, which is reasonable, but it should be stated clearly if that is the intent.
Proposed resolution (October, 2012):
Change 12.2.4.2.6 [over.ics.list] paragraph 2 as follows:
If the parameter type is std::initializer_list<X> or “array of X”134 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, or if the initializer list has no elements, the identity conversion. This conversion can be a user-defined conversion even in the context of a call to an initializer-list constructor. [Example:
void f(std::initializer_list<int>); f( {} ); // OK: f(initializer_list<int>) identity conversion f( {1,2,3} ); // OK: f(initializer_list<int>) identity conversion f( {'a','b'} ); // OK: f(initializer_list<int>) integral promotion f( {1.0} ); // error: narrowing ...