2

このテンプレートのインスタンス化を試みていますが、うまくいきません。エラーが発生します:

prog.cpp:7:15: error: template-id 'f<const A&, A()>' for 'void f()' does not match any template declaration

template <class T, T> void f() {}

struct A {};

template void f<const A &, A()>();

int main() {}

メインで実行すると機能するため、これは奇妙です。

int main() {
    const A &a = A(); // no error
}

では、なぜテンプレート行で機能しないのでしょうか?

4

2 に答える 2

2

テンプレート引数を一時オブジェクトにすることはできません。完全に等しいかどうかを合理的に比較できるプリミティブ型のみが、型のない引数をテンプレートにすることができます。これも

  • 整数、
  • 列挙子、および
  • externリンケージを持つオブジェクトへのポインター。

しかし

  • 浮動小数点数は、非常に近いが等しくない可能性があるため、許可されていません
  • staticオブジェクトは同じ名前を持っていても、別のファイルでは別の場所にある可能性があります。これにより、テンプレート ID が別のファイル内の同じ名前の別のインスタンス化に紛らわしく解決されます。
  • 同じことが文字列リテラルにも当てはまります
  • 一時オブジェクトには一貫したアドレスがないため、ポインターを渡すことはできません
  • 渡された一時オブジェクトの値は、等しいかどうかをテストすることさえできず、言語がテンプレートのインスタンス化を別のテンプレートに一致させることはありません!

(Pubby が指摘しているように、A()実際には、パラメーターを返さない関数の型として解釈されますA。そのため、コンパイラーは、2 つの型パラメーターを受け取るテンプレート宣言を見つけることができません。)

于 2013-01-04T03:08:40.393 に答える
2

非型テンプレート パラメータの重複の可能性

これらは、テンプレートの非型パラメーターの規則です

非タイプのテンプレート パラメータは、次の (オプションで cv 修飾された) タイプのいずれかを持つ必要があります。

  • 整数型または列挙型、
  • オブジェクトへのポインタまたは関数へのポインタ、
  • オブジェクトへの左辺値参照または関数への左辺値参照、
  • メンバーへのポインター、
  • std::nullptr_t.

あなたが渡しているのはRValue(代入できない一時オブジェクトなど)であり、これらの可能性のいずれにも該当しません。

編集:

実際には関数型として解釈されているように見えますが、テンプレート署名は型の型以外のパラメーターを期待していますA(正確にはconst A&)

于 2013-01-04T03:11:13.120 に答える