exponenta event banner

Правило AUTOSAR C++ 14 A14-5-3

Универсальный оператор, не являющийся членом, должен быть объявлен только в пространстве имен, которое не содержит объявлений типа класса (struct), типа перечисления или типа объединения.

Описание

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

Универсальный оператор, не являющийся членом, должен быть объявлен только в пространстве имен, которое не содержит объявлений типа класса (struct), типа перечисления или типа объединения.

Объяснение

Это правило запрещает размещение универсальных операторов в том же пространстве имен, что и объявления типа класса (struct), типа перечисления или типа объединения. Если в качестве параметров шаблона используются типы class, enum или union, наличие универсальных операторов в одном пространстве имен может вызвать неожиданное разрешение вызовов.

Рассмотрим пространство имен NS который объединяет класс B и общая форма operator==:

namespace NS {
   class B {};
   template <typename T> bool operator==(T, std::int32_t);
}
Если используется класс B в качестве параметра шаблона для другого общего класса, такого как этот класс шаблона A:
template <typename T> class A {
    public:
      bool operator==(std::int64_t);
}

template class A<NS::B>;
все пространство имен NS используется для разрешения перегрузки при операторах класса A называются. Например, если вы звоните operator== с int32_t аргумент, дженерик operator== в пространстве имен NS с int32_t используется вместо параметра operator== в исходном классе шаблона A с int64_t параметр. Вы или другой разработчик или рецензент кода могут ожидать, что вызов оператора решит operator== в исходном классе шаблона A.

Внедрение Polyspace

Для каждого универсального оператора средство проверки правил определяет, содержит ли пространство имен объявления типов классов, типов перечислений или типов объединения. Если такое объявление найдено, средство проверки помечает нарушение правил на самом операторе.

Средство проверки также помечает универсальные операторы, определенные в глобальном пространстве имен, если глобальное пространство имен также имеет объявления класса, перечисления или объединения.

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

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

Примеры

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

#include <cstdint>

template <typename T> class Pair {
    std::int32_t item1;
    std::int32_t item2;
    public:
      bool operator==(std::int64_t ItemToCompare);
      bool areItemsEqual(std::int32_t itemValue) {
          return (*this == itemValue);
      }
};

namespace Operations {
    class Data {};
    template <typename T> bool operator==(T, std::int32_t); //Noncompliant
}

namespace Checks {
    bool checkConsistency();
    template <typename T> bool operator==(T, std::int32_t); //Compliant
}

template class Pair<Operations::Data>;

В этом примере пространство имен Operations нарушает правило, поскольку оно содержит тип класса Data рядом с родовым operator==. Пространство имен Checks не нарушает правило, поскольку единственное другое объявление в пространстве имен, кроме общего operator==, является объявлением функции.

В методе areItemsEqual в template class Pair<Operations::Data>, == операция вызывает generic operator== метод в Operations пространство имен. Вызов разрешает это operator== метод, основанный на типе данных аргумента (std_int32_t). Этот метод лучше соответствует по сравнению с operator== метод в исходном классе шаблона Pair.

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

Группа: Шаблоны
Категория: Консультации, Автоматизированные