「T&&」パラメータを使用して関数テンプレートをオーバーロードすることは一般的に悪い考えです。これは何にでもバインドできるためですが、とにかくそれを行うと仮定しましょう。
template<typename T>
void func(const T& param)
{
std::cout << "const T&\n";
}
template<typename T>
void func(T&& param)
{
std::cout << "T&&\n";
}
私の理解では、const T&
オーバーロードは定数値である引数に対して呼び出され、T&&
オーバーロードは他のすべての引数タイプに対して呼び出されます。func
ただし、constおよびnon-constコンテンツの配列を使用して呼び出すとどうなるかを考えてみてください。
int main()
{
int array[5] = {};
const int constArray[5] = {};
func(array); // calls T&& overload
func(constArray); // calls const T& overload
}
VC10、VC11、およびgcc 4.7は、示されている結果に同意します。私の質問は、2番目の呼び出しがなぜconst T&
オーバーロードを呼び出すのかということです。簡単な答えはconstArray
、constが含まれているということですが、それは単純すぎると思います。推定されるタイプT(選択されたテンプレートに関係なく)は「5const intsの配列」であるためparam
、const T&
オーバーロードのタイプは「5constintsのconst配列への参照」になります。ただし、constArrayという名前の配列自体は、constとして宣言されていません。では、なぜオーバーロードを呼び出さないので、func(constArray)
「5つの定数の配列への参照」 T&&
のタイプが生成されるのでしょうか。param
この質問は、c ++テンプレート関数の引数の推定と関数の解決での質問に関連する議論によって動機付けられていますが、スレッドは他の問題で脇道に追いやられ、私が今ここで尋ねている質問を明確にしなかったと思います。