AUTOSAR C++14 Rule A5-1-2

Переменные не должны быть неявно получены в лямбда-выражении.

Описание

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

Переменные не должны быть неявно получены в лямбда-выражении.

Объяснение

В лямбда-выражении у вас есть опция, чтобы получить переменные неявно. Например, это лямбда-выражение

[&](std::int32_t var) {
   sum+ = var;
}
указывает, что все локальные переменные в контексте вызова получены ссылкой. Однако это не сразу понятно от этого лямбда-выражения:

  • Если переменная в органе по выражению прибывает из контекста вызова.

    Например, в предыдущем лямбда-выражении, это не ясно если sum получен от контекста вызова или глобальная переменная.

  • Если все переменные, полученные от контекста вызова, используются и изменяются ли переменные или только читаются (Если переменные читаются, получение копией предпочтено).

Если вы получаете переменные явным образом в лямбда-выражении, вы имеете больше контроля на том, получить ли ссылкой или копией. Кроме того, вы или рецензент можете считать лямбда-выражение и определить, была ли переменная получена от контекста вызова.

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

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

Примеры

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

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdint>

void addEvenNumbers(std::vector<std::int32_t> numbers)
{
    std::int64_t sum = 0;
    std::int32_t divisor = 2;
    for_each(numbers.begin(), numbers.end(), [&] (std::int32_t y) //Noncompliant
    {
        if (y % divisor == 0)
        {
            std::cout << y << std::endl; 
            sum += y;
        }
    });
 
    std::cout << sum << std::endl;
}

void addOddNumbers(std::vector<std::int32_t> numbers)
{
    std::int64_t sum = 0;
    std::int32_t divisor = 2;
    for_each(numbers.begin(), numbers.end(), [&sum, divisor] (std::int32_t y) //Compliant
    {
        if (y % divisor != 0)
        {
            std::cout << y << std::endl; 
            sum += y;
        }
    });
 
    std::cout << sum << std::endl;
}

Лямбда-выражение в addEvenNumbers функционируйте получает все локальные переменные в контексте вызова неявно ссылкой и нарушает это правило. Некоторые проблемы:

  • Если вы не проходите по телу выражения, это не ясно, какие переменные используются.

  • Хотя переменная divisor только читается и не изменяется, это получено ссылкой. Получение копией предпочтено.

Лямбда-выражение в addOddNumbers функционируйте получает каждую переменную явным образом и не нарушает это правило. Не смотря на тело лямбда-выражения, можно определить, какие переменные предназначаются, чтобы быть измененными в выражении.

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

Группа: Выражения

Введенный в R2019b