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

Что делает auto &&?

Это код из С++ 11 Notes Sample by Scott Meyers,

int x;
auto&& a1 = x;             // x is lvalue, so type of a1 is int&
auto&& a2 = std::move(x);  // std::move(x) is rvalue, so type of a2 is int&&

У меня возникли проблемы с пониманием auto&&.
У меня есть некоторое понимание auto, из которого я бы сказал, что auto& a1 = x должен сделать тип a1 как int&

Какой из котируемого кода кажется неправильным.

Я написал этот маленький код и пробежал под gcc.

#include <iostream>

using namespace std;

int main()
{
    int x = 4;
    auto& a1 = x;           //line 8
    cout << a1 << endl;
    ++a1;
    cout << x;
    return 0;
}

Выход = 4 (newline) 5
Затем я изменил строку 8 как auto&& a1 = x; и побежал. Тот же выход.

Мой вопрос: auto& равно auto&&?
Если они отличаются от того, что делает auto&&?

4b9b3361

Ответ 1

Код правильный. auto&& p = expr означает, что тип p равен T&&, где T будет выведено из expr. Здесь && указывает ссылку на rvalue, например,

auto&& p = 1;

выведет T == int, и, следовательно, тип p будет int&&.

Однако ссылки могут быть свернуты в соответствии с правилом:

T& &   == T&
T& &&  == T&
T&& &  == T&
T&& && == T&&

(Эта функция используется для реализации идеальной пересылки в С++ 11.)

В случае

auto&& p = x;

as x является lvalue, ссылка rvalue не может быть привязана к нему, но если мы выберем T = int&, тогда тип p станет int& && = int&, который является ссылкой на lvalue, которая может быть связана до x. Только в этом случае auto&& и auto& дают тот же результат. Эти два отличаются друг от друга, например,

auto& p = std::move(x);

неверно, поскольку std::move(x) является rvalue, а ссылка lvalue не может быть привязана к нему.

Прочитайте С++ Rvalue References Explained для прогулок.