Что значит двойной амперсанд (&&) в параметрах функции и как его использовать?
1,00
р.
р.
Перехожу в одиннадцатый стандарт из старого и в нем много нового для меня, в частности не понятно для чего в параметрах функций пишут двойной амперсанд &&. Неясно для чего он нужен и как его можно использовать? Вот небольшой примерчик: 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' будет неопределено.