次の小さな例は私の問題を示しています。
template<class T> struct X
{
static void xxx(T& x) { }
static void xxx(T&& x) { }
};
int main(int argc, char** argv)
{
int x = 9;
X<int>::xxx(x); // OK.
X<int&>::xxx(x); // ERROR!
return 0;
}
エラーメッセージ(GCC):
エラー:'static void X :: xxx(T &&)[with T = int&]'はオーバーロードできません
エラー:with' static void X :: xxx(T&)[with T = int&]'</ p>
なんで?T = int&
---> inにT&
置き換えられますか?int&&
static void xxx(T& x)
質問に対する答えが「はい」の場合、次のようになります。
T&
は左辺値参照ではなく、右辺値参照になります。- そして、次のコードが機能するはずです。
しかし、そうではありませんでした:
template<class T> struct X
{
static void xxx(T& x) { }
};
int main(int argc, char** argv)
{
X<int&>::xxx(2); // ERROR!
return 0;
}
エラーメッセージ(GCC):
エラー:'X :: xxx(int)'の呼び出しに一致する関数がありません<br>注:候補は次のとおりです:static void X :: xxx(T&)[with T = int&]
その場合T&
、withT = int&
は等しくT&&
なく、右辺値参照でもありません。しかし、そうでない場合、なぜ最初の例が機能しないのですか?(これは再帰的な問題です!)
しかし、同様の問題はポインター型では発生しませんでした。
#include <iostream>
template<class T> struct X
{
static void xxx(T* x) { std::cout << **x << std::endl; }
};
int main(int argc, char** argv)
{
int x = 10;
int* xx = &x;
X<int*>::xxx(&xx); // OK. call X<int*>::xxx(int**)
return 0;
}
この動作で参照が異なるのはなぜですか?