AUTOSAR C++14 Rule A8-5-4

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

Описание

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

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

Объяснение

Если класс содержит конструктора, который берет параметр типа std::initializer_list и другой конструктор параметрами, заключенные в фигурные скобки инициализации, такие как:

classType obj {0,1}
Может привести к беспорядку, о котором из этих двух конструкторов вызывается. Компиляторы предпочитают конструктора с std::initializer_list параметр, но разработчики может ожидать в противном случае.

Реализация Polyspace

Средство проверки отмечает определения классов, которые содержат конструктора, первый параметр которого имеет тип std::initializer_list и также содержит другого конструктора (исключая специальных конструкторов функции членства). Нарушение правила сопровождается событиями, которые указывают на местоположение других конструкторов, которые могут привести к беспорядку с std::initializer_list конструктор.

Определение класса с std::initializer_list- у конструктора параметра, который не нарушает это правило, есть только значение по умолчанию, копия и конструкторы перемещения (и копия и операторы присваивания перемещения). Если вы не можете избежать второго конструктора параметрами, можно выровнять по ширине это нарушение правила. В этом случае, для инициализации списком, используйте синтаксис, такой как:

classType obj ({0,1})
так, чтобы было ясно что std::initializer_list- конструктор параметра вызывается. Для инициализации другими конструкторами используйте синтаксис, такой как:
classType obj (0,1)
Оба вызова являются исключениями к Правилу A8-5-2, которое обычно отмечает инициализации с помощью (), но позволяет такие инициализации для классов с соединением std::initializer_list- конструктор параметра и другие конструкторы.

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

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

Примеры

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

#include <cstdint>
#include <initializer_list>
#include <vector>

//Noncompliant class definition
class entrySizes {//Noncompliant
    public:
       entrySizes()=default;
       entrySizes(std::size_t aCurrentSize, std::size_t aLastSize): 
              currentSize{aCurrentSize}, lastSize{aLastSize} {}
       entrySizes(std::initializer_list<std::size_t> sampleEntry): 
              currentSize{sampleEntry.size()}, lastSize{sampleEntry.size()} {}
    private:
       std::size_t currentSize;
       std::size_t lastSize;
};

//Compliant class definition
class recordSizes {//Compliant
    public:
       recordSizes()=default;
       recordSizes(std::initializer_list<std::size_t> sampleRecord): 
              currentSize{sampleRecord.size()}, lastSize{sampleRecord.size()} {}
    private:
       std::size_t currentSize;
       std::size_t lastSize;
};

//Calls to constructors from noncompliant class
void createEntry() {
    entrySizes defaultEntrySize{};
    entrySizes stdEntrySize{0,1}; 
       //Calls entrySizes(std::initializer_list<std::size_t> ), 
       //but developer might expect otherwise
    entrySizes expectedEntrySize({0,1}); 
       //Calls entrySizes(std::initializer_list<std::size_t> ), 
       //but developer might expect otherwise
    entrySizes typicalEntrySize(1,1); 
        //Calls entrySizes(std::size_t, std::size_t)
}

//Calls to constructors from compliant class
void createRecord() {
    recordSizes defaultRecordSize{};
    recordSizes stdRecordSize{0,1}; 
       //Calls recordSizes(std::initializer_list<std::size_t> )
}

В этом примере, класс entrySizes содержит двух пользовательских конструкторов, один с std::initialize_list параметр и второй с двумя size_t параметры. Присутствие двух конструкторов может привести к беспорядку разработчика как показано в createEntry функция. В случае, если вы хотите сохранить текущее определение класса и выровнять по ширине нарушение правила, createEntry функционируйте также показывает более чистый способ вызвать std::initialize_list- конструктор параметра.

Класс recordSizes не нарушает правило, поскольку оно не содержит другого конструктора кроме конструктора по умолчанию и конструктора с std::initialize_list параметр.

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

Группа: операторы объявления
Категория: консультация, автоматизированная
Введенный в R2021a