Невозможно преобразовать параметр из 'int' в 'int &'
Я слежу за курсом С++ по множественным значениям, и в нем есть следующий код:
#include <iostream>
template <class T>
T max(T& t1, T& t2)
{
return t1 < t2 ? t2 : t1;
}
int main()
{
std::cout << "Max of 33 and 44 is " << max(33, 44) << std::endl;
return 0;
}
Я набрал этот фрагмент кода, но в отличие от кода курса, я получаю сообщение об ошибке:
C2664: 'max' : cannot convert parameter 1 from 'int' to 'int &'
Код в курсе написан в Visual Studio Express 2010, а мой написан в Visual Studio Ultimate 2010.
ИЗМЕНИТЬ
Спасибо всем (даже самой Кейт Грегори) за ответы и расчистку.
Ответы
Ответ 1
Поскольку литералы (и rvalues в целом) не могут быть переданы неконстантной ссылкой (поскольку это не имеет смысла, если вызывающий может их изменить). Либо перейдите по значению, либо по ссылке const:
template <class T>
T max(const T& t1, const T& t2)
{
return t1 < t2 ? t2 : t1;
}
или
template <class T>
T max(T t1, T t2)
{
return t1 < t2 ? t2 : t1;
}
Ответ 2
Оба 33 и 44 являются значениями r; они передаются функции по значению, а не по ссылке. Компилятор не может преобразовать эти два в ожидаемый тип int &
. Используйте переменные (lvalues), поскольку они могут передаваться по ссылке:
int a = 33, b = 44;
max(a, b); // 44
Поскольку вы просто имеете дело с фундаментальными типами здесь (int
), передача по ссылке является избыточной. Передача по значению вызывает копию, но разница будет незначительной:
template <class T>
T max(T t1, T t2);
Здесь мы можем передать оба значения и lvalues. Но есть вероятность, что вы можете передать объект типа класса. В этом случае рекомендуется прохождение по ссылке.
Но для случая, когда мы не хотим копировать и хотим как lvalues, так и rvalues, мы можем передать ссылку const
:
template <class T>
T max(T const &t1, T const &t2);
В С++ 11 вы можете передать аргументы универсальной ссылкой, чтобы мы могли связывать glvalues:
template <class T>
T max(T&& t1, T&& t2);
int main()
{
int a{0}, b{0};
max(a, b);
max(1, 2);
}
Если вы хотите сохранить синтаксис lvalue-reference в своем исходном коде, вы можете использовать этот lvalue shim:
template<typename T>
T& lvalue(T&& t)
{
return t;
}
int main()
{
max(lvalue(1), lvalue(2));
}
Ответ 3
Ответ здесь оказывается в неродственном коде, который вы не использовали в своем тесте. Абсолютно мой маленький max() должен принимать либо по значению, либо по const-ref, и это было всего лишь промахом мозга, которое я исправлю, как только смогу.
Но полный демо-код работает красиво. Это потому, что оно включает в себя больше заголовков, один из которых приводит к бесполезности и, следовательно, std::max
. Это заставило меня не заметить, что мой max
не использовался. Я повторю демоверсию с именем типа biggest
, чтобы устранить это снова. И тем временем, да, если вы хотите передать литералы в функцию по ссылке, они должны быть const ref. Я знал это, но не думал об этом при написании тестового жгута, а затем был обманут, когда появился плохой код. Мне следовало бы перечитать код более внимательно: спасибо, что вызвали это на мое внимание. (И спасибо за курс, и я надеюсь, что вы найдете его полезным.)
Ответ 4
Вы не можете передать временное значение T&
. Поскольку вы не изменяете аргументы, используйте const T&
вместо
Кстати, есть встроенная функция max
Ответ 5
Целочисленные литералы не могут передаваться как неконстантная ссылка. Кроме того, ваша функция max
может работать с ссылками const
, поэтому отметьте их соответствующим образом:
T max(const T& t1, const T& t2)
Ответ 6
Если вы определили свою функцию с параметрами по ссылке, вы не можете использовать ничего, кроме имен переменных для указанных параметров, - и вы пытаетесь использовать числа.
Ответ 7
Небольшое замечание. Вы можете использовать свой начальный код функции " max". Попробуйте изменить вызов от max(34, 44)
до max<const int>(34,44)
. Иногда это может быть полезно.
#include <iostream>
template <class T>
T max(T& t1, T& t2)
{
return t1 < t2 ? t2 : t1;
}
int main()
{
std::cout << "Max of 33 and 44 is " << max<const int>(33, 44) << std::endl;
return 0;
}