Что говорит «auto my_var =» против «auto & my_var =»? - PullRequest
1 голос
/ 23 сентября 2019

В чем разница между написанием:

auto my_var = [expression];

и

auto& my_var = [expression];

A) Что сообщается?

B) Гарантируется ли первая версиябыть копией?(когда, когда нет?)

C) Когда следует использовать второе 'auto &'?

Обновление:

Один из примеров - выражениеоценивается как ссылка:

#include <vector>

int main() {
    auto  ints = std::vector{-1};

    auto front_int = ints.front();//front returns a reference, but 'auto' doesn't reflect that (giving us a copy instead)
    front_int = 0;

    return ints.front();//returns '-1', we didn't update the vector
}

Поначалу это может показаться не интуитивным (хотя это имеет смысл, если вы попытаетесь взглянуть на более широкую картину).Чтобы «исправить», нам нужно использовать auto& версию, - но почему это именно так?

1 Ответ

5 голосов
/ 23 сентября 2019

Что сообщается?

Тип my_var передается.my_var - это объявленная переменная.Более конкретно, амперсанд (или его отсутствие) сообщает, является ли тип эталонным или нет.

гарантируется ли первая версия как копия?

гарантированно будет отдельным объектом.

Однако копирование не гарантируется.Это зависит от выражения.Если это значение, то копия не будет, поскольку C ++ 17;Переменная будет инициализирована выражением напрямую.В противном случае существует копия (или перемещение, если тип имеет конструктор перемещения и если выражение является значением xvalue или если оно является prvalue до C ++ 17) в отношении абстрактной машины.Но в некоторых случаях это копирование / перемещение может быть исключено на практике.

Пример, демонстрирующий отсутствие какого-либо копирования.Следующая программа корректно сформирована на C ++ 17:

struct not_opyable_nor_movable {
    not_opyable_nor_movable()                          = default;
    not_opyable_nor_movable(not_opyable_nor_movable&)  = delete;
    not_opyable_nor_movable(not_opyable_nor_movable&&) = delete;
};

not_opyable_nor_movable function() {
    return {};
}

int main() {
    auto my_var = function();
}

, когда следует использовать второй 'auto &'?

Когда вы хотите объявить lvalueссылка.Пример:

int foo{};
auto& myvar = foo;
myvar = 42; // foo is now 42

нам нужно использовать auto & version, - , но почему именно это ?

Поскольку кажется, что вы хотитевнести изменения в объект, на который ссылается результат вызова функции.Для этого необходимо внести изменения через ссылку.Амперсанд используется для объявления ссылки.

...