AUTOSAR C++14 Rule 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>, а == операция вызывает типовой operator== метод в Operations пространство имен. Вызов разрешается к этому operator== метод, основанный на типе данных аргумента (std_int32_t). Этот метод является лучшим по сравнению с operator== метод в исходном классе шаблона Pair.

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

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