В следующем небольшом примере показана моя проблема:
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):
error: 'static void X :: xxx (T &&) [with T= int &] 'не может быть перегружено
ошибка: с' static void X :: xxx (T &) [с T = int &] '
Почему?T = int&
---> Заменено T&
на int&&
в static void xxx(T& x)
?
Если ответ на вопрос положительный, то:
T&
не является lvalue-ссылкой и становится rvalue-ссылкой! - И следующий код должен работать:
Но это не так:
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)'
примечание: кандидаты: static void X :: xxx (T &)[с T = int &]
Тогда T&
с T = 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;
}
Почему ссылки отличаются в этом поведении?