AUTOSAR C++14 Rule A14-8-2
Explicit specializations of function templates shall not be used
説明
ルール定義
関数テンプレートの明示的特殊化は使用されないものとします。
根拠
関数テンプレートの明示的特殊化は、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 から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。
例
チェック情報
| グループ: テンプレート |
| カテゴリ: Required、Automated |
バージョン履歴
R2020a で導入