exponenta event banner

Правило AUTOSAR C++ 14 A7-1-5

Автоспецификатор должен использоваться только в следующих случаях: (1) объявить, что переменная имеет тот же тип, что и возвращаемый тип вызова функции, (2) объявить, что переменная имеет тот же тип, что и инициализатор непринципиального типа, (3) объявить параметры обобщенного лямбда-выражения, (4) объявить шаблон функции, используя синтаксис завершающего возвращаемого типа

Описание

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

Автоспецификатор должен использоваться только в следующих случаях: (1) объявить, что переменная имеет тот же тип, что и возвращаемый тип вызова функции, (2) объявить, что переменная имеет тот же тип, что и инициализатор непринципиального типа, (3) объявить параметры обобщенного лямбда-выражения, (4) объявить шаблон функции, используя синтаксис завершающего возвращаемого типа.

Объяснение

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

Это правило разрешает использование auto спецификатор в этих случаях:

  • Объявляется переменная, инициализируемая вызовом функции. Это позволяет избежать повторения типа и обеспечивает отсутствие неожиданных преобразований при изменении возвращаемого типа функции. Например, в этом фрагменте кода переменная var имеет тот же тип, что и возвращаемый тип myfunc():

    #include<cstdint>
    
    int32_t myfunc();
    
    int foo(){
      auto var=myfunc();
      return var;
    }

  • Объявляется переменная, инициализируемая инициализатором фундаментального типа. Тип T не является фундаментальным, если std::is_fundatmental<T>::value имеет значение false. Список фундаментальных типов см. в разделе Фундаментальные типы. Например, тип var в этом фрагменте кода std::vector<int>::iterator.

    std::vector<int> v = { 1, 2, 3};
    auto var = v.begin();
    С помощью auto ключевое слово, вы делаете код более читаемым и избегаете необходимости писать трудный для запоминания непринципиальный тип.

    Обратите внимание, что указатель не является фундаментальным типом.

  • Объявляются параметры базовой лямбда-функции. Затем функция может принимать несколько типов параметров, подобных шаблону функции. Например, пользовательская реализация std::sort в этом фрагменте кода может использоваться для сортировки векторов ints, floats или других арифметических типов.

    //sort in ascending order
    std::sort(v.begin(), v.end(),
                  [](auto lhs, auto rhs){
                      return lhs < rhs});
    

  • Для объявления шаблона функции используется синтаксис конечного возвращаемого типа. В этом случае вычет по типу отсутствует. auto ключевое слово используется как часть альтернативного синтаксиса для объявления шаблонов функций. Этот фрагмент кода показывает пример синтаксиса конечного возвращаемого типа.

    template<typename T, typename U>
    auto subtract(T lhs, U rhs) -> decltype(lhs - rhs);
    

Внедрение Polyspace

  • Polyspace ® помечает использование auto спецификатор, за исключением случаев, когда он используется в одном из вариантов, перечисленных в предыдущем разделе.

  • Polyspace помечает использование auto объявление переменной, инициализированной с помощью std::initializer_list фундаментального типа.

  • Polyspace не помечает использование decltype(auto).

Поиск неисправностей

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

Примеры

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

#include <string>
#include<vector>

auto func(int a)   // Non-compliant
{
    return a;
}

void func2()
{
    auto int_type = new int[5];           //  Non-compliant

    auto vector_type = std::vector<int> { 1, 2, 3 }; // Compliant

    const char* c = "hello";
    auto str2 =  std::string(c); // Compliant

    auto lambda = [](auto x, auto y) { // Compliant
        return x > y;
    };


}


В этом примере использование auto спецификатор для возвращаемого типа func не соответствует требованиям. Выведенный тип возврата функции может быть неочевидным. Аналогичным образом, использование auto в декларации int_type несовместим, поскольку инициализатор этой переменной является массивом типа int, который является фундаментальным типом.

Другие виды использования auto в этом примере соответствуют сценариям использования, указанным в этом правиле:

  • Инициализаторы vector_type и str2 являются непринципиальными типами std::vector<int> и stdd::string соответственно (вариант использования (2)).

  • Инициализатор переменной lambda является лямбда-выражением нефундаметального типа (вариант использования (2))

  • Переменные x и y - параметры лямбда-выражения (вариант использования (3)).

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

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