Для удобства я буду ссылаться на параметр, который изменяется функцией как «out-param».
Out-params можно передавать как неконстантные ссылки. Там нет технической причины не делать этого. Например, в стандартных библиотеках std::swap
принимает два параметра по ссылке и изменяет оба.
В прошлом я видел, как правило, в руководстве по стилю, что выходные параметры должны передаваться по указателю, а не по ссылке. Мотивация этого заключается в том, что некоторые люди [*]
хотят, чтобы вызов функции появлялся , чтобы передать объект по значению, чтобы оставить объект неизмененным. Это позволяет им рассуждать о куске кода, просто взглянув на вызывающий код, без необходимости искать то, что на самом деле делает функция. Например:
int foo(int a) {
return a + 1;
}
int bar(int &a) {
return ++a;
}
Теперь, учитывая int i = 0;
, вызовы foo(i)
и bar(i)
выглядят абсолютно одинаково, но один из них ведет себя как хорошая, простая функция C, тогда как другой использует для передачи * 1015 передачу по ссылке *.
Некоторые люди [*]
хотят, чтобы эти разные вещи явно отличались на сайте вызовов, поэтому они предпочли бы написать bar(&i)
, чтобы дать понять, что i
можно изменить [**]
. По сути, они предпочли бы, чтобы в C ++ вообще не было неконстантных ссылок в качестве параметров функции.
Не обязательно что-то плохое в том, что эти люди хотят сделать. Например, вы можете придерживаться его в случае std::swap
, всегда используя вместо него std::iter_swap
. Но большинство руководств по стилю C ++ не имеют такого правила.
[*]
например, программисты на C
[**]
Фактически, в моей функции bar
, a
является одновременно входным и выходным параметром. Их предпочтительная функция int bar(int *pa);
технически не имеет внешнего параметра, хотя для удобства они, вероятно, будут ссылаться на референд pa
(то есть i
) как на дополнительный параметр, и каждый знает, что это значит .