5

次のコードは正常にコンパイルされます。

template<typename T>
void f(const T &item) { return; }

int main() 
{
  f("const string literal");
}

ideone でコンパイル成功: http://ideone.com/dR6iZ

しかし、戻り値の型について言及すると、コンパイルされません。

template<typename T>
T f(const T &item) { return item; }

int main() 
{
  f("const string literal");
}

今ではエラーが発生します:

prog.cpp:6: エラー: 'f(const char [21])' の呼び出しに一致する関数がありません</p>

ideone のコード: http://ideone.com/b9aSb

戻り値の型const Tにしてもコンパイルされません

私の質問は:

  • なぜコンパイルされないのですか?
  • 戻り値の型は、エラーと関数テンプレートのインスタンス化にどのような関係がありますか?
4

2 に答える 2

15

関数から配列を返すことはできないため、テンプレートのインスタンス化は失敗し、一致する関数はありません。

SFINAEが原因でこの特定のエラーが発生します。実際には、コンパイラが関数をインスタンス化できないというエラーでなく、一致する関数がないというエラーです。

配列への参照を返すことができます-返すT const &ことは機能します。

編集: コメントへの応答:

まず、これは実際に SFINAE の適切な例です。

template<typename T> T f(const T &item) { return item; }
char const * f(void const * item) { return 0; }
int main() {
  f("abc");
}

コンパイラがこれをコンパイルすると、最初にテンプレート化された f をインスタンス化して、 type に完全に一致するものを作成しようとしますconst char [3]。前述の理由により、これは失敗します。次に、不正確な一致、単純な関数を選択し、呼び出しでconst char [3]を a に減衰させconst char *ます。

于 2011-03-15T02:15:18.107 に答える
0

T を返すつもりだと言っているように見えますが、実際には const T& を返します。宣言を次のように変更してみてください。

template<typename T>
const T& f(const T& item) { return item; }

または、戻り値を引数の逆参照バージョンに変更することもできます。

template<typename T>
T f(const T& item) { return (*item); }
于 2011-03-15T02:21:41.123 に答える