7

次のコードを検討してください。

#include <iostream>


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

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


int fun_i()
{
    return 0;
}

const int fun_ci()
{
    return 0;
}

int main()
{
    f(fun_i());
    f(fun_ci());
}

これを MSVC 2012 でコンパイルすると、出力は次のようになります。

f(int&&)
f(const int&&)

GCC 4.7 でコンパイルすると、出力は次のようになります。

f(int&&)
f(int&&)

どちらが正しい?

(f の 2 番目の定義を削除すると、プログラムは MSVC 2012 ではコンパイルされませんが、GCC 4.7 ではコンパイルされます。)

4

2 に答える 2

9

GCCは正しいです。3.10 左辺値と右辺値 [basic.lval] の段落 4 から:

クラスの prvalue は、cv 修飾された型を持つことができます。非クラスの prvalue は、常に cv 修飾されていない型を持ちます。[...]

のような関数呼び出しfun_ci()は、実際には prvalue* であり、そのため型intは ではなくconst intです。int&&は よりもよく一致const int&&し、オーバーロードの解決によって選択する必要があります。

*: トップレベルの cv-qualifiers は、非クラスの戻り値の型では無視されると慣習的に言われています。

于 2012-08-28T14:01:22.673 に答える
2

gcc が出力する警告に基づいて、gcc は正しいことをしているように見えると言いたいです。

stieber@gatekeeper:~$ g++ -std=c++11 -Wignored-qualifiers Test.cpp
Test.cpp:20:18: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
于 2012-08-28T14:01:39.223 に答える