Страницы

Поиск по вопросам

пятница, 5 октября 2018 г.

Что значит двойной амперсанд (&&) в параметрах функции и как его использовать?

Перехожу в одиннадцатый стандарт из старого и в нем много нового для меня, в частности не понятно для чего в параметрах функций пишут двойной амперсанд &&. Неясно для чего он нужен и как его можно использовать?
Вот небольшой примерчик:
void test(int && a){ a++; // как работать с таким параметром (а) внутри функции, например вывести ее на экран? }
int main(){ int a = 1;
test(a); // как передать переменную?
return 0; }


Ответ

Пока читаете, для себя такое небольшое правило выработал:
type& - аргумент обязательно lvalue, т.е. то, что стоит слева от знака равно:
int a = 1; foo(a); // a может быть изменено в foo и по выходу иметь другое значение foo(1); // ошибка компиляции const type& - аргумент может быть как lvalue (при этом даёте гарантию, что он там не поменяется) или rvalue, тогда его время жизни продлевается на время вызова:
int a = 1; bar(a); // а не меняется внутри bar(2); // тоже легально type&& - аргумент может быть только rvalue, при этом внутри вызова можно его изменять и вообще, работаете как с обычной переменной (как только rvalue внутри функции обретает имя, оно "автоматом" становится lvalue :-)). Чтобы обычную переменную превратить в rvalue, нужно её "переместить", т.е. по сути, отдать владение в вызываемую функцию:
int a = 1; baz(a); // ошибка компиляции baz(std::move(a)); // всё отлично, но после вызова состояние a не определено. baz(2); // тоже отлично, 2 - rvalue const type&& - такая конструкция возможна, но её смысл для меня ускальзывает. Она сродни такому:
void some(const int arg);
т.е. просто внутри менять запрещаете.
Из правил вытекает использование: когда нужно отдать владение объектом. Возможна просто дополнительная перегрузка, чтобы можно было работать в одинаковом стиле в вызывающем коде как с rvalue, так и lvalue:
void foo(int& a); // [1] void foo(int&& a); // [2] ... int a = 1; foo(a); // вызовется [1] foo(1); // вызовется [2] foo(move(a)); // вызовется [2], состояние 'a' будет неопределено.

Комментариев нет:

Отправить комментарий