Как передать "буквальные" целые числа по ссылке в С++ (Newbie)
Изменить:. Как отмечают многие люди, перекрестная ссылка обычно не подходит для оптимизации для примитивных типов. Это прекрасно знать, так что спасибо всем! Тем не менее, мой вопрос был действительно больше о том, почему буквальные значения не могут быть переданы по ссылке, которые были рассмотрены принятым ответом. Ура!
(Простите мою наивность: я довольно новичок в С++.)
Чтобы избежать неэффективности копирования по значению при вызове функции (скажем, "fillRect" ), я хочу передать параметры по ссылке.
Если я укажу параметры как объявленные локальные переменные, он работает нормально. Но если я поставлю любые как "буквальные" целые числа, я получаю ошибку компиляции (без соответствующей функции).
void fillRect( int &x, int &y, int &width, int &height )
{
// do something
}
int x=10, y=20, w=100, h=80;
fillRect(x, y, w, h); // this compiles and works!
fillRect(x, y, 100, 80); // but this doesn't compile ... why?
Что дает?
Ответы
Ответ 1
Вы не можете привязать литерал к ссылке lvalue для не-const (потому что изменение значения литерала не является операцией, которая имеет смысл). Однако вы можете привязать литерал к ссылке на const.
Итак, это скомпилируется, если вы объявите fillRect
как:
void fillRect(int const& x, int const& y, int const& width, int const& height)
В этом случае вы проходите int
s. int
настолько дешевы, чтобы скопировать то, что они передают по ссылке, вероятно, ухудшат производительность вашей программы.
Функция fillRect
, вероятно, настолько дорога, что стоимость передачи своих аргументов в любом случае абсолютно не имеет значения. Или, может быть, он будет встроен, и не будет никаких затрат на передачу аргументов. Такие виды микрооптимизации обычно не являются оптимизациями и всегда должны руководствоваться результатами профилирования (если они вообще выполняются).
Ответ 2
Чтобы избежать неэффективности копирования по значению при вызове функции
Остановитесь здесь.
Передача по ссылке не обязательно означает "быстрый". Это вдвойне подходит для базовых типов. Действительно, доступ к базовым типам по ссылке будет медленнее, чем при использовании по стоимости. Ссылка не магия. Он обычно реализуется как указатель. Поэтому каждый раз, когда вы получаете доступ к этому значению, вы, вероятно, выполняете разыменование указателя.
Это звучит как какая-то микро-оптимизация. Не оптимизируйте без профилирования. Если у вас нет веских оснований ожидать, что производительность вашего приложения зависит от значений по сравнению с ссылочными параметрами, просто делайте то, что имеет смысл.
Вы должны передавать только базовые типы по ссылке, если вы собираетесь их модифицировать.
Ответ 3
Передача по ссылке на самом деле медленнее для таких малых значений. Чтобы передать по ссылке, она находится под капотом, передавая указатель (который в любом случае является значением размера по умолчанию). Затем есть скрытая дополнительная указательная ссылка, которая не является бесплатной. Прямо просто передать значение.
Сделайте это:
void fillRect( int x, int y, int width, int height )
{
// do something
}
Компилятор, скорее всего, встроит вашу функцию в любом случае, если не будет большой. Таким образом, вы не смогли бы улучшить производительность, будучи "умными" в том, как вы объявили эту функцию.
Ответ 4
Сначала вы должны обратить внимание на другой совет, чтобы предпочесть переходить по значению для простых типов. C (и по расширению С++) были разработаны с учетом этого варианта использования и для того, для чего они оптимизированы.
Во-вторых, вы всегда должны использовать ссылку const
, если не собираетесь изменять эту переменную. Литерал может быть привязан к константной ссылке, но не неконстантной.
Ответ 5
Кажется, вы уже знакомы с проблемами copy-by- value, поэтому вы исключили значение copy-by- . И теперь вы смущены тем, что передача исходных значений не выполняется?
Теперь я потерян.
Ответ 6
Во-первых, C не поддерживает передачу переменной по ссылке. Это поддерживает С++.
Возможное решение:
#include<stdio.h>
void fillRect( int &x, int &y, int &width, int &height )
{
printf("%d %d %d %d",x,y,width,height);
}
int main()
{
int x=10, y=20, w=100, h=80;
fillRect(x, y, w, h); // this compiles and works!
int temp1 = 100;
int temp2 = 80;
fillRect(x, y,temp1, temp2); // but this doesn't compile ... why?
return 0;
}
u cant перегрузка, потому что это вызывает неоднозначность.