AUTOSAR C++14 Rule A5-1-4

Объект лямбда-выражения не должен переживать ни один из своих полученных ссылкой объектов

Описание

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

Объект лямбда-выражения не должен переживать ни один из своих полученных ссылкой объектов.

Объяснение

Правило отмечает случаи, где лямбда-выражение получает объект ссылкой, и можно потенциально получить доступ к полученному объекту вне его осциллографа. Эта ситуация происходит, если объект лямбда-выражения переживает объект, полученный ссылкой.

Например, рассмотрите этот функциональный createFunction:

std::function<std::int32_t()> createFunction() {
   std::int32_t localVar = 0;
   return ([&localVar]() -> std::int32_t {
       localVar = 1;
       return localVar;
   });
}

createFunction возвращается лямбда-выражение возражают, что получает локальную переменную localVar ссылкой. Осциллограф localVar ограничивается createFunction но возвращенный объект лямбда-выражения имеет намного больший осциллограф.

Эта ситуация может привести к попытке получить доступ к локальному объекту localVar вне его осциллографа. Например, когда вы вызываете createFunction и присвойте возвращенный объект лямбда-выражения другому объекту aFunction:

auto aFunction = createFunction();
и затем вызовите новый объект aFunction:
std::int32_t someValue = aFunction();
полученная переменная localVar больше не находится в осциллографе. Поэтому значение, возвращенное от aFunction isundefined.

Если функция возвращает лямбда-выражение, чтобы не получать доступ к полученному объекту вне его осциллографа, убедитесь, что лямбда-выражение получает все объекты копией. Например, можно переписать createFunction как:

std::function<std::int32_t()> createFunction() {
   std::int32_t localVar = 0;
   return ([localVar]() mutable -> std::int32_t {
       localVar = 1;
       return localVar;
   });
}

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

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

развернуть все

auto createAdder(int amountToAdd) {
  int addThis = amountToAdd; //Noncompliant
  auto adder = [&] (int initialAmount) {
      return (initialAmount + addThis);
  };
  return adder;
}
 
void foo() {
  auto AddByTwo = createAdder(2);
  int res = AddByTwo(10);
}

auto createMultiplier(int amountToMultiply) {
  int multiplyThis = amountToMultiply; //Compliant
  auto adder = [=] (int initialAmount) {
      return (initialAmount + multiplyThis);
  };
  return adder;
}


void bar() {
  auto MultiplyByTwo = createMultiplier(2);
  int res = MultiplyByTwo(10);
}

В этом примере, createAdder функция задает лямбда-выражение adder это получает локальную переменную addThis ссылкой. Осциллограф addThis ограничивается createAdder функция. Когда объект AddByTwo, который возвращен createAdder, называется, ссылка на переменную addThis получен доступ вне его осциллографа. Когда получено доступ таким образом, значение addThis isundefined.

Проблема не происходит с createMultiplier функция, которая возвращает лямбда-выражение, которое получает локальные переменные копией.

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

Группа: Выражения
Категория: необходимый, автоматизированный
Введенный в R2019b