33

§3.10 セクション 9 は、「非クラスの右辺値には常に cv 修飾されていない型がある」と述べています。それは私を驚かせました...

int foo()
{
    return 5;
}

const int bar()
{
    return 5;
}

void pass_int(int&& i)
{
    std::cout << "rvalue\n";
}

void pass_int(const int&& i)
{
    std::cout << "const rvalue\n";
}

int main()
{
    pass_int(foo()); // prints "rvalue"
    pass_int(bar()); // prints "const rvalue"
}

標準によると、非クラス型の const 右辺値などはありませんbar()が、 にバインドすることを好みconst int&&ます。これはコンパイラのバグですか?

EDIT:どうやら、thisconst rvalueでもあります:)

編集: この問題は g++ 4.5.0 で修正されたようです。両方の行で "rvalue" が出力されるようになりました。

4

2 に答える 2

2

いい視点ね。1)非クラスの右辺値のことを指摘したように、2)オーバーロードの解決がどのように機能するか:

最適な関数の選択基準は、引数の数、引数が候補関数のパラメータ タイプ リストとどの程度一致するかです [...]

非クラスの右辺値がオーバーロードの解決中に特別に扱われることを示す標準は見たことがありません。

あなたの質問は、私が持っている標準のドラフトでカバーされていますが(N-4411)、多少:

ただし、参照バインディング、暗黙的な変換シーケンス、参照、および一般的なオーバーロードの解決を並行して読み取ることが関係します。

13.3.3.1.4 参照バインディング

2 参照型のパラメータが引数式に直接バインドされていない場合、変換シーケンスは、13.3.3.1 に従って、引数式を参照の基になる型に変換するために必要なものです。

13.3.3.2 暗黙的な変換シーケンスのランキング

3 同じ形式の 2 つの暗黙的な変換シーケンスは、次の規則のいずれかが適用されない限り、区別できない変換シーケンスです。

— 標準変換シーケンス S1 は、標準
変換シーケンス S2よりも優れた変換シーケンスです。

— S1 と S2 は参照バインディング (8.5.3) であり、どちらも参照修飾子なしで宣言された非静的メンバー関数の暗黙的なオブジェクト パラメーターを参照せず、S1 が左辺値参照を左辺値にバインドし、S2 が右辺値参照をバインドするか、または S1右辺値参照を右辺値にバインドし、S2 は左辺値参照をバインドします。

[ 例:

int i;
int f();
int g(const int&);
int g(const int&&);
int j = g(i); // calls g(const int&)
int k = g(f()); // calls g(const int&&)
于 2010-01-31T00:16:24.547 に答える