このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
MISRA C++:2023 Rule 17.8.1
説明
ルール定義
Function templates shall not be explicitly specialized. 1
根拠
関数テンプレートの明示的特殊化は、C++ でのオーバーロード解決に伴う予期せぬ問題を引き起こす可能性があります。オーバーロード解決:
まず、一致するパラメーター リストをもつ非テンプレートの plain old 関数を探します。
このような関数が見つからない場合は、オーバーロード解決が最も近い関数テンプレートを選択します。
関数テンプレートを選択したら、コンパイラは選択されたテンプレートの適切な特殊化を検索します。
テンプレートの特殊化では、オーバーロード解決プロセスの順序が変更されないため、予期せず、理解できない動作が生じる可能性があります。次のコード スニペットを考えてみましょう。
//(a) base template template<class T> void f( T ); //(b) specialization of (a) template<> void f<>(int*); //... //(c) overloads (a) template<class T> void f( T* ); //... main(){ int *p; f( p ); }
f()
が main()
で int*
を使用して呼び出される場合は、(b) でマークされている int*
の特殊化が呼び出されると想定します。コンパイラは、次のように、f()
の呼び出しを解決します。
コンパイラは、入力型が
int*
の plain old 関数を検索します。このような関数は存在しないため、コンパイラは、最も近いパラメーター リストをもつ関数テンプレートを検索します。
汎用ポインターを入力として取得するテンプレート (c) が
f(int*)
に最も近いものです。テンプレート (c) は特殊化されていません。オーバーロード解決プロセスが停止して、(c) でテンプレートが呼び出されます。
int*
型の入力用に特殊化されたテンプレートが (b) で定義されていたとしても、関数呼び出しは代わりに (c) でテンプレートに解決されます。これは、予期せぬ動作です。
オーバーロードされた関数テンプレートを特殊化すると、オーバーロードされたテンプレートのうち、どのテンプレートが特殊化されるかは、宣言の順序によって決まります。次のコード スニペットを考えてみましょう。
//(a) template <typename T> void F1(T t){} //(b) template <typename T> void F1(T* p){} //(x): Specialization of template template <> void F1<>(uint16_t* p){}
//(a) template <typename T> void F1(T t){} //(x): Specialization of template template <> void F1<>(uint16_t* p){} //(b) template <typename T> void F1(T* p){}
わかりにくいコードと予期せぬ動作を回避するには、関数テンプレートの特殊化を回避します。関数テンプレートを特殊化する必要がある場合は、クラス テンプレートにデリゲートする単一の関数テンプレートを作成します。たとえば、以下のコードでは、関数テンプレート f()
がクラス f_implementation
にデリゲートします。
template<class T> class f_implementation; template<class T> void f( T t ) { FImpl<T>::f( t ); //Don't specialize function template } template<class T> class f_implementation { static void f( T t ); // Specializing class templates is permissible. }
Polyspace 実装
関数テンプレートを明示的に特殊化すると、Polyspace® がその関数テンプレートにフラグを設定します。
トラブルシューティング
ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。
例
チェック情報
グループ: Templates |
カテゴリ: Required |
バージョン履歴
R2024b で導入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.