3.3非タイプテンプレートパラメータの制限
3.3 タイプ以外のテンプレートパラメータの制限
非型テンプレートパラメータにはいくつかの制限があることに注意してください。一般的に、彼らは
定数の整数値(列挙を含む)、オブジェクト/関数/メンバーへのポインター、オブジェクトまたは関数への左辺値参照、またはstd :: nullptr_t(nullptrのタイプ)のみである必要があります。
タイプではないテンプレートパラメータは制限されていることに注意してください。一般的に言えば、それらは定数整数(列挙を含む)、オブジェクト/関数/メンバーへのポインター、オブジェクトまたは関数への左辺値参照、またはstd :: nullptr_t(nullptrのタイプ)のみです。
浮動小数点数とクラス型オブジェクトは、型なしテンプレートとしては許可されていません
パラメーター:
浮動小数点およびクラスオブジェクトは、非タイプテンプレートパラメータとして許可されていません:
template < double VAT> // エラー:浮動小数点数は非型テンプレートパラメータとして使用できません double process(double v)// しかし、テンプレートパラメータとして使用できます { return v * VAT; } template <std :: string name> // エラー:クラスタイプは非タイプテンプレートパラメータ クラスとして使用できません MyClass { // テンプレートパラメータとして許可 … };
テンプレート引数をポインターまたは参照に渡す場合、オブジェクトは文字列リテラル、一時オブジェクト、またはデータメンバーと他のサブオブジェクトであってはなりません。これらの制限はC ++ 17より前のすべてのC ++バージョンで緩和されたため、追加の制約が適用されます。
テンプレート引数へのポインターまたは参照を渡す場合、オブジェクトを文字列リテラル、一時オブジェクトまたはデータメンバー、およびその他のサブオブジェクトにすることはできません。C ++ 17より前のすべてのC ++バージョンではこれらの制限が緩和されているため、次の制限が追加されます。
•C ++ 11では、オブジェクトには外部リンケージも必要でした。
C ++ 11では、オブジェクトには外部リンクも必要です。
•C ++ 14では、オブジェクトには外部または内部リンケージも必要でした。
C ++ 14では、オブジェクトも外部または内部でリンクする必要があります。
したがって、以下は不可能です。
したがって、以下は不可能です。
template < char const * name> class MyClass { … }; MyClass < " hello " > x; // エラー:文字列リテラルは許可されていません( "hello")
ただし、回避策があります(これもC ++バージョンによって異なります)。
ただし、いくつかの回避策があります(これもC ++バージョンに依存します)。
extern char const s03 [] = " hi " ; // 外部リンク char const s11 [] = " hi " ; // 内部リンク int main() { メッセージ <s03> m03; // OK(すべてのバージョン) メッセージ<s11 > m11; // C ++から始まるOK 11 static char const s17 [] = " hi " ; // リンクなし(静的ローカル変数はリンクなし?) メッセージ<s17> m17; // C +からOK +17開始 }
3つのケースすべてで、定数文字配列は「hello」によって初期化され、このオブジェクトはchar const *で宣言されたテンプレートパラメータとして使用されます。これは、オブジェクトに外部リンケージがある場合(s03)、C ++ 11およびC ++ 14の場合、内部リンケージがある場合(s11)、すべてのC ++バージョンで有効です。リンケージがない場合はC ++ 17以降です。 。
3つのケースすべてで、定数文字配列オブジェクトは「hello」によって初期化されます。このオブジェクトは、char const *として宣言されたテンプレートパラメータで使用されます。オブジェクトが外部リンク(s03)の場合、C ++のすべてのバージョンが有効です。C ++ 11およびC ++ 14では、オブジェクトが内部リンクの場合、それも機能します。C ++ 17以降では、オブジェクトがまったくリンクされていなくても機能します。
詳細については、194ページのセクション12.3.3を、354ページのセクション17.2は、この領域で将来起こり得る変更についての説明を参照してください。
詳細については、194ページのセクション12.3.3を参照してください。将来この場所が変更される可能性については、354ページのセクション17.2を参照してください。
無効な式の回避
無効な式を避ける
タイプのないテンプレートパラメータの引数は、コンパイル時の式です。
例えば:
タイプではないテンプレートパラメータは、コンパイル時に任意の式にすることができます。
template < int I、bool B> クラスC; … C < sizeof(int)+ 4、sizeof(int)== 4 > c;
ただし、式でoperator>を使用する場合、ネストされた>が引数リストを終了するように、式全体を括弧で囲む必要があることに注意してください。
ただし、式で ">"演算子を使用した場合は、式全体を括弧で囲んで、>引数の終了リストをネストする必要があることに注意してください。
C < 42、sizeof(int)> 4 > c; // エラー:最初の ">"はテンプレート引数リストを終了します C < 42、(sizeof(int)> 4)> c; // OK