17

ユニバーサル リファレンスで遊んでいるときに、clang と gcc がオーバーロードの解決について意見が一致しないこのインスタンスに出くわしました。

#include <iostream>

struct foo {};

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

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

int main()
{
    foo f;
    bar(f);  // ambiguous on gcc, ok on clang
}

gcc は、上記の呼び出しがあいまいであると報告しています。ただし、clangはオーバーロードを選択し、T&正常にコンパイルします。

どのコンパイラが間違っていますか? その理由は?

編集:
VS2013 プレビューで同じコードをテストし、clang に同意します。gcc側にあるIntellisenseを除いて:-)

4

1 に答える 1

18

「ユニバーサル リファレンス」は、パラメータを に推測しますfoo&。最初のテンプレートも、パラメータを に推定しfoo&ます。

C++ には、関数テンプレートの部分的な順序規則がT&あり、より特殊化されていT&&ます。したがって、サンプル コードでは最初のテンプレートを選択する必要があります。

于 2013-07-31T19:34:03.167 に答える