MISRA C++:2008 Rule 14-5-1

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

Описание

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

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

Объяснение

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

Считайте пространство имен 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.

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

Группа: шаблоны
Категория: необходимый
Введенный в R2020b