メインコンテンツ

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

A non-member generic function shall only be declared in a namespace that is not an associated namespace

説明

ルール定義

A non-member generic function shall only be declared in a namespace that is not an associated namespace. 1

根拠

このルールは、クラス (struct) 型、列挙型、または共用体型の宣言と同じ名前空間への汎用関数の配置を禁止しています。クラス型、列挙型、または共用体型がテンプレート パラメーターとして使用されている場合は、同じ名前空間内に汎用関数が存在すると、予期せぬ呼び出し解決が発生する可能性があります。汎用関数は、クラス型、列挙型、または共用体型と関連付けることができない名前空間にのみ配置してください。

クラス Boperator== の一般形式を組み合わせた名前空間 NS を考えます。

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>;
クラス A の演算子が呼び出されたときに、名前空間 NS 全体がオーバーロード解決に使用されます。たとえば、int32_t 引数を指定して operator== を呼び出すと、名前空間 NS 内の汎用 operator==int32_t パラメーターが、オリジナルのテンプレート クラス A 内の operator==int64_t パラメーターの代わりに使用されます。開発者またはコード レビュー担当者は、オリジナルのテンプレート クラス A 内の operator== に解決するための演算子呼び出しを想定する可能性があります。

Polyspace 実装

汎用関数ごとに、ルール チェッカーが、配置先の名前空間にクラス型、列挙型、または共用体型の宣言も含まれているかどうかを判断します。このような宣言が見つかった場合は、チェッカーが演算子自体に対するルール違反にフラグを設定します。

また、グローバル名前空間にもクラス、列挙、または共用体の宣言が含まれている場合は、チェッカーがグローバル名前空間で定義された汎用関数にもフラグを設定します。

トラブルシューティング

ルール違反が想定されるものの、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 がルールに違反します。これは、汎用 operator== と一緒にクラス型 Data が含まれているためです。一方、名前空間 Checks はルールに違反しません。これは、この名前空間には、汎用 operator== の他に関数宣言しか含まれていないためです。

template class Pair<Operations::Data> 内のメソッド areItemsEqual では、== 演算子によって、Operations 名前空間内の汎用 operator== メソッドが呼び出されます。呼び出しは、引数データ型 (std_int32_t) に基づいて、この operator== メソッドに解決されます。このメソッドは、オリジナルのテンプレート クラス Pair 内の operator== メソッドよりも適切です。

チェック情報

グループ: テンプレート
カテゴリ: 必要

バージョン履歴

R2020b で導入


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.