Поделиться через


lnt-accidental-copy

Выполняется копирование, поскольку auto не выводит ссылки.

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

Проверка lnt-accidental-copy контролируется настройкой Случайное копирование в параметрах стиля кода C/C++. Сведения о том, как изменить этот параметр, см. в разделе Настройка анализатора кода.

Примеры

#include <string>
#include <vector>

std::string& return_by_ref();

int& return_int_by_ref();

void accidental_copy(std::vector<std::string>& strings)
{
    for (auto s : strings) {} // Flagged: A new copy of each string is
                              // made when the vector is iterated.

    auto s = return_by_ref(); // Flagged: the function returns by-reference
                              // but a copy is made to initialize 's'.

    auto i = return_int_by_ref(); // Not flagged because no copy constructor is called.
}

Устранение проблемы

Исправление, предложенное анализатором кода, — заменить auto на auto& в объявлении.

#include <string>

std::string& return_by_ref();

void accidental_copy(std::vector<std::string>& strings)
{
    for (auto& s : strings) {}

    auto& s = return_by_ref();
}

Замечания

Предлагаемое исправление можно применять не во всех случаях. Исправление может вызвать ошибку компиляции или изменить поведение кода. Важно понимать, как предлагаемое исправление влияет на код, прежде чем применять его.

В случаях, когда возвращается временный результат, требуется const auto&, чтобы предотвратить ошибку компиляции. В этом случае может быть предпочтительнее продолжать использование auto.

Иногда копирование выполняется намеренно, например, если нужно изменить копию, не затрагивая исходный экземпляр, как показано в этом примере.

void modifies_string(std::string& s);

void example(std::vector<std::string>& strings)
{
    for (auto s : strings) {
        modifies_string(s);    // In this case, the copy may be intended so that
                               // the original strings are not modified.
    }
}

См. также

Обзор анализатора кода IntelliSense для C++