「C++ and Beyond 2012: Universal References」のプレゼンテーションで、Scott は繰り返しその点を強調しています。つまり、ユニバーサル参照はすべてを処理/バインドするため、既にユニバーサル参照パラメーターを受け取る関数をオーバーロードすることは意味がありません。と混ざるまでは、疑う理由がありませんでしたstd::initializer_list
。
以下に短い例を示します。
#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;
}
奇妙なことに、VC11 2012 年 11 月 CTP はあいまいさについて不平を言っています ( error C2668: 'foo' : ambiguous call to overloaded function
)。さらに驚くべきことは、gcc-4.7.2、gcc-4.9.0、clang-3.4 が次の出力で一致していることです。
initializer list
initializer list
initializer list
universal reference
したがって、(gcc と clang をinitializer_list
使用して) s でユニバーサル参照を取る関数をオーバーロードすることは明らかに可能ですが、 - イディオムを使用する場合は、 by 値auto + { expr } => initializer_list
を取るか by を取るかが問題になります。少なくとも私にとっては、その行動はまったく驚くべきものでした。標準に準拠している動作はどれですか? その背後にあるロジックを知っている人はいますか?initializer_list
const&