Подтвердить что ты не робот

Как передать "буквальные" целые числа по ссылке в С++ (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?

Что дает?

4b9b3361

Ответ 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 перегрузка, потому что это вызывает неоднозначность.