ユニバーサル参照によって任意の型を受け入れることができる関数があり、特定の型に対してオーバーロードしたいと考えています (そのうちのいくつかはそれ自体がテンプレート化されていますが、ここでは重要ではないと思います)。残念ながら、オーバーロードを正しい順序で解決することはできないようです。
の 2 番目の宣言は、より具体的である (テンプレート化されていない) ため、優先されると推測していましたがfoo
、オーバーロードの解決に関する私の理解がやや不足しているようです。興味深いことに、2 番目の宣言をX
値で受け取るように変更すると、「良い、良い」とX
出力され、非 const 参照で受け取ると「悪い、良い」と出力されます。明らかに、最初の宣言を完全に削除すると、他に選択肢がないため、「良い、良い」が返されます。
では、なぜこれが起こるのですか?そして最も重要なことは、次のコードが機能しない場合、このシグネチャを使用して関数をオーバーロードするにはどうすればよいでしょうか?
#include <iostream>
#include <string>
class X {};
template<typename T>
inline std::string foo(T && rhs) {
return "bad";
}
inline std::string foo(const X & rhs) {
return "good";
}
int main() {
std::cout << foo(X()) << std::endl;
X x;
std::cout << foo(x) << std::endl;
return 0;
}
編集:
おそらく、これに対するより遠回りな解決策は、間接的に行うことです。の最初の形式を取り除き、foo
SFINAE を使用して有効なオーバーロードが存在するかどうかを確認しますfoo_fallback
。