複数のファイルinline
に含まれている場合、テンプレート関数は必要ですか? cpp
ありがとう。
template<bool> inline QString GetText();
template<> inline QString GetText<true>() {return "true";}
template<> inline QString GetText<false>() {return "false";}
複数のファイルinline
に含まれている場合、テンプレート関数は必要ですか? cpp
ありがとう。
template<bool> inline QString GetText();
template<> inline QString GetText<true>() {return "true";}
template<> inline QString GetText<false>() {return "false";}
これらは完全な関数の特殊化であるため、通常の関数と同じように 1 つの定義規則に従う必要があります。
はい、inline
指定子が必要です。
ODR (1 定義規則) は、変数、関数、クラス、列挙型、またはテンプレートの定義が 1 つだけ存在する必要があることを示しています。あなたの質問に関連する例外は、§3.2/5 (C++11) にリストされています (私の強調):
クラス型 (条項 9)、列挙型 (7.2)、外部リンケージを持つインライン関数 (7.1.2)、クラス テンプレート (条項 14)、非静的関数テンプレート (14.5.6) の複数の定義が存在する可能性があります。 、クラス テンプレートの静的データ メンバー (14.5.1.3)、クラス テンプレートのメンバー関数 (14.5.1.1)、または一部のテンプレート パラメータが指定されていないテンプレートの特殊化(14.7、14.5.5)。定義は別の翻訳単位に表示され、定義が次の要件を満たしていることが条件です。[...]
すべてのパラメーターが指定されているテンプレートの特殊化 (つまり、明示的な特殊化) はそこにリストされておらず、§14.7.3/12 は次のように述べています。
関数テンプレートの明示的な特殊化は、関数テンプレートがインラインであるかどうかに関係なく、インライン指定子で宣言されているか、削除されていると定義されている場合にのみインラインです。[ 例:
template<class T> void f(T) { /∗ ... ∗/ } template<class T> inline T g(T) { /∗ ... ∗/ } template<> inline void f<>(int) { /∗ ... ∗/ } // OK: inline template<> int g<>(int) { /∗ ... ∗/ } // OK: not inline
— 終了例 ]
テンプレート宣言のインライン化の理由はありませんが、テンプレートの完全な特殊化の理由はありません。最初の行に inline キーワードを追加する必要はありませんが、2 行目と 3 行目には必要です。ただし、テンプレートを使用する各翻訳単位にはテンプレート定義を含める必要があるため、ヘッダー ファイルに含めて、それを使用する他の cpps に含めるのが最善の方法です。
3.2/6 の C++ 標準 n3376 では、定義が同じであれば、アプリケーション全体のクラス テンプレートの複数の定義が存在する可能性があります。
===============
Jesse Good のコメントに基づいて回答を更新します (テンプレートの完全な特殊化にはインラインが必要です)。Jesse Good の指摘に感謝します。