AUTOSAR C++14 Rule A18-9-4

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

Описание

Управляйте определением

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

Объяснение

Вы обычно используете 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