AUTOSAR C++14 Rule A18-9-4

Аргумент std:: forward не используется впоследствии

Описание

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

Аргумент std:: forward впоследствии не используется.

Объяснение

Обычно вы используете std::forward в шаблоне функции, чтобы передать параметр ссылки переадресации в другую функцию. Ресурсы параметра могут быть переданы другому объекту посредством операции перемещения, в зависимости от категории значения параметра.

Для параметра rvalue параметр находится в неопределенном состоянии, если он перемещается из после вызова в std::forward и его не следует использовать повторно.

Для параметра lvalue, Если вы повторно используете параметр после вызова std::forward, изменения параметра могут повлиять на аргумент функции вызывающего абонента, которому вы передаете параметр.

Реализация Polyspace

Polyspace® помечает вызов, на который std::forward если переадресуемый объект повторно используется после вызова. Polyspace также подсвечивает линии, где пересланный объект повторно используется в вашем коде.

Polyspace не помечает вызов std::forward если его аргумент повторно используется в ветви, которая не может быть достигнута после вызова std::forward. Например, в этом фрагменте кода ветвь, где повторно используется переменная t не может быть достигнуто после того, как код входит в ветвь, где std::forward используется.

template<typename T>
void func(T&& t)
{
  T&& p = t;

  switch(t) { 
    case 0:
      p = std::forward<T>(t); 
      break;
    case 1:
      t--; //t reused 
      break;
  }
}

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

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

Примеры

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

#include <cstdint>
#include <iostream>
#include <utility>

namespace myTemplates
{

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

template<typename T>
void f2(T&& t2, bool b)
{
    if (b) {
        f1(std::forward<T>(t2)); // Compliant
    } else {
        t2++;  // else branch not entered
    }

}


template<typename T>
void f3(T&& t3)
{
    T&& p = std::forward<T>(t3); // Non-compliant

    switch (t3) {                // t3 reused
    case 0:
        t3++;                    // t3 reused
        break;
    case 1:
        t3--;                    // t3 reused
        break;
    default:
        break;
    }
}


template<typename T>
void f4(T&& t4)
{
    --t4;

    f1(std::forward<T>(t4)); // Non-compliant

    t4++;                    // t4 reused

    f1(std::forward<T>(t4)); // Non-compliant and t4 reused

    t4--;                    // t4 reused
}


template<typename T>
void f5(T&& t5)
{
    f1(t5,                   // t5 reused
       std::forward<T>(t5)); // Non-compliant
}

}

void main(void)
{
    int i;

    myTemplates::f2(i, true);
    myTemplates::f3(i);
    myTemplates::f4(i);
    myTemplates::f5(i);

}

В этом примере Polyspace помечает все вызовы, чтобы std::forward где переадресованный параметр повторно используется после вызова. В функции шаблона f4, второй вызов std::forward отсчитывает как повторное использование параметра t4. Нарушений этого правила нет в f2 потому что t2 повторно используется в else ветвь, которая никогда не вводится.

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

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