AUTOSAR C++14 Rule A18-9-2

Переадресация значений на другие функции осуществляется через: (1) std:: move, если значение является ссылкой rvalue, (2) std:: forward, если значение является ссылкой на переадресацию

Описание

Определение правила

Переадресация значений на другие функции осуществляется через: (1) std:: move, если значение является ссылкой rvalue, (2) std:: forward, если значение является ссылкой на переадресацию.

Объяснение

Можно эффективно передать объект в функцию, приведя объект в rvalue и воспользовавшись семантикой перемещения.

  • Если вы пересылаете ссылку rvalue на функцию, используйте std::move чтобы привести объект к значению rvalue.

  • Если вы пересылаете ссылку на переадресацию (или универсальную ссылку) в функцию, используйте std::forward чтобы привести объект к значению rvalue тогда и только тогда, когда объект связан с значением rvalue. Ссылка на пересылку может быть связана с rvalue или lvalue. В целях этого правила объекты с типом auto && рассматриваются как ссылки на пересылку.

Использование std::move с переадресацией ссылок может привести к неожиданному изменению значения lvalue. Использование std::forward с rvalue ссылки возможны, но это подвержено ошибкам и может увеличить сложность вашего кода.

Реализация Polyspace

  • Polyspace® флаги использования std::move переадресация ссылки на функцию, включая объекты типа auto &&.

  • Polyspace помечает использование std::forward чтобы переслать ссылку rvalue на функцию.

  • Polyspace не помечает использование std::move или std::forward если переадресация на функцию не выполняется. Например, в этом фрагменте кода не возникает дефекта при использовании std::move с ссылкой на пересылку b2 и использование std::forward с ссылкой перезначения b1.

    template <typename T1, typename T2>
    void func(T1& b1, T2&& b2)
    {
        const T1& b10 = std::forward<B>(b1);
        const T2& b20 = std::forward<B>(b2);
        const T1& b11 = std::move(b1);
        const T2& b21 = std::move(b2);
    }

Поиск и устранение проблем

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

расширить все

#include <cstdint>
#include <string>
#include <utility>


class A
{
public:
    explicit A(std::string&& s)
        : str(std::move(s)) // Compliant
    {
    }

private:
    std::string str;
};

template <typename ...T>
void f1(T...t);



template <typename T1, typename T2>
void func(T1&& t1, T2& t2)
{
    f1(std::move(t1));            // Non-compliant
    f1(std::forward<T1>(t1));     // Compliant

    f1(std::forward<T2>(t2));     // Non-compliant
    f1(std::move(t2));            // Compliant
}

void func_auto(A& var)
{
    auto&& var1 = var;
    f1(std::move(var1));                    // Non-compliant
    f1(std::forward<decltype(var1)>(var1)); //Compliant
}

void main()
{
    int32_t i;
    func(0, i);
}

В этом примере функция шаблона func пересылает параметры t1 и t2 для функционирования f1. Polyspace помечает использование std::forward с t2 поскольку этот параметр является ссылкой rvalue (тип T&).

Polyspace также помечает использование std::move с t1 поскольку этот параметр является ссылкой на пересылку (тип T&&). Если t1 инициализируется с помощью lvalue, перемещение может привести к неожиданному изменению параметра. Точно так же Polyspace помечает использование std::move в func_auto из-за объектов типа auto&& рассматриваются как ссылки на пересылку.

Проверяйте информацию

Группа: Библиотека языковой поддержки
Категория: Необходимый, Автоматизированный
Введенный в R2020b