8

ユニバーサル参照によって任意の型を受け入れることができる関数があり、特定の型に対してオーバーロードしたいと考えています (そのうちのいくつかはそれ自体がテンプレート化されていますが、ここでは重要ではないと思います)。残念ながら、オーバーロードを正しい順序で解決することはできないようです。

の 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;
}

編集:

おそらく、これに対するより遠回りな解決策は、間接的に行うことです。の最初の形式を取り除き、fooSFINAE を使用して有効なオーバーロードが存在するかどうかを確認しますfoo_fallback

4

2 に答える 2

4

Xからへの変換は、テンプレート化されたオーバーロードとorconst Xの直接一致よりも悪いと見なされます。T = XT = X &

于 2013-05-22T14:53:39.287 に答える