exponenta event banner

Правило AUTOSAR C++ 14 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 поскольку этот параметр является ссылкой на пересылку (type T&&). Если t1 инициализируется с помощью lvalue, перемещение может привести к неожиданному изменению параметра. Аналогично, Polyspace помечает использование std::move в func_auto потому что объекты типа auto&& рассматриваются как ссылки на пересылку.

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

Группа: Библиотека поддержки языка
Категория: Обязательно, Автоматизировано
Представлен в R2020b