1

このコード ( http://ideone.com/Mo7fQrで入手可能)

template<typename T>
void f(const T&) { std::cout << "const T& overload\n"; }

template<typename T>
void f(T&&) { std::cout << "T&& overload\n"; }

int main()
{
  const int x = 0;

  f(x);                 // calls const T& overload
  f(std::move(x));      // calls T&& overload
}

への最初の呼び出しf(左辺値を使用) はconst T&オーバーロードを呼び出し、2 番目の呼び出し (右辺値を使用) はT&&オーバーロードを呼び出します。少なくとも、gcc 4.8.1 と最新の VC++ (VC12) ではそうです。

2 番目の呼び出しがこのように解決される理由を理解していると思います。最初のテンプレートはパラメーターを取得するようにインスタンス化されconst int&ますが、2 番目のテンプレートはconst int&&パラメーターを取得するようにインスタンス化されます。呼び出しサイトで渡される引数は右辺値であるため、優先的にバインドされます。右辺値参照。(これは、C++11 標準の 13.3.3.2/3 の箇条書き 1 のサブ箇条書き 4 で指定されていると思います。)

しかし、 への最初の呼び出しではf、両方のテンプレートがタイプ のパラメータを取るようにインスタンス化しますconst int&constでは、左辺値が渡されたときに最初のテンプレートが優先されるのはなぜですか?

4

1 に答える 1

1

同じ関数テンプレートの特殊化を複数の宣言から生成できる場合、宣言は、C++11 標準 §14.5.6.2 関数テンプレートの部分的な順序付け [temp.func.order] で説明されているように、関数テンプレートの部分的な順序付けを使用して明確化されます。 . コンパイラは、どのテンプレートが最も特殊化されているかを判断し、それを優先します。

あなたの例では、のconst T&オーバーロードはオーバーロードfよりも特化していT&&ます。直観的に、T&&できるものは何でも推論できますconst T&が、その逆はできないため、const T&より具体的であり、したがってその関数のオーバーロードはより専門的です。

于 2013-07-20T07:37:51.130 に答える