In his "C++ and Beyond 2012: Universal References" presentation, Scott repeatedly stresses the point, that universal references handle/bind to everything and thus overloading a function that already takes a universal reference parameter does not make sense.
I had no reason to doubt that until I mingled them with std::initializer_list
.
Here is a short example:
#include <iostream>
#include <initializer_list>
using namespace std;
template <typename T>
void foo(T&&) { cout << "universal reference" << endl; }
template <typename T>
void foo(initializer_list<T>) { cout << "initializer list" << endl; }
template <typename T>
void goo(T&&) { cout << "universal reference" << endl; }
template <typename T>
void goo(initializer_list<T> const&) { cout << "initializer list" << endl; }
int main(){
auto il = {4,5,6};
foo( {1,2,3} );
foo( il );
goo( {1,2,3} );
goo( il );
return 0;
}
Oddly enough, VC11 Nov 2012 CTP complains about ambiguity (error C2668: 'foo' : ambiguous call to overloaded function
). Yet even more suprising is, that gcc-4.7.2, gcc-4.9.0 and clang-3.4 agree on the following output:
initializer list
initializer list
initializer list
universal reference
So apparently it is possible (with gcc and clang) to overload functions taking universal references with initializer_list
s but when using the auto + { expr } => initializer_list
-idiom it does even matter whether one takes the initializer_list
by value or by const&
.
At least to me that behavior was totally surprising.
Which behavior conforms to the standard? Does anyone know the logic behind that?
Overloading + URef almost always an error. Makes no sense: URefs handle everything. [...]
– Herringtemplate <class T> void f(initializer_list<T>)
is more specialized thantemplate <class T> void f(T&&)
. Simple tests with GCC seem to confirm this too (not necessarily usinginitializer_list
as container). – Intravenoustemplate <class T> void f(initializer_list<T>)
is more specialized thantemplate <class T> void f(T&&)
but the crux is it doesn't care. Overload selection first ranks based on the conversion sequence, then if there's no best overload yet on some other criteria including partial ordering ("more specialized"). – Demonize