3
char f1();
void f2(char&);

struct A {};

A    f3();
void f4(A&);

int main()
{
    f2(f1()); // error C2664. This is as expected.
    f4(f3()); // OK! Why???
}

エラー C2664: 'void f4(char &)': 引数 1 を 'char' から 'char &' に変換できません

私は、C++ では非 const 参照パラメーターを一時オブジェクトにバインドできないと教えられました。上記のコードでは、f2(f1());期待どおりにエラーが発生します。

しかし、なぜ同じルールがコード行に適用されないのf4(f3());でしょうか?

PS: 私のコンパイラは VC++ 2013 です。行にコメントを付けても、f2(f1());含まれているコードはf4(f3());エラーや警告なしでコンパイルされます。

アップデート:

MSDNは次のように述べています。

Visual C++ の以前のリリースでは、非 const 参照を一時オブジェクトにバインドできました。現在、一時オブジェクトは const 参照にのみバインドできます。

なのでVC++のバグだと思います。バグレポートをVC++ チームに提出しました

4

2 に答える 2

4

/Za オプションを指定してコンパイルして言語拡張機能を無効にすると、コンパイラは両方の呼び出しを拒否します。

> cl /Za test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
test.cpp(11): error C2664: 'void f2(char &)' : cannot convert argument 1 from 'char' to 'char &'
test.cpp(12): error C2664: 'void f4(A &)' : cannot convert argument 1 from 'A' to 'A &'
        A non-const reference may only be bound to an lvalue

言語拡張機能が有効になっているコンパイラが、非 const 左辺値参照を右辺値式にバインドできるようにする (非常に制約された) 状況がいくつかあります。私の理解では、これは主に、この「拡張機能」に依存するいくつかの巨大なレガシー コードベースを壊さないようにするためのものです。

(一般に、/Za の使用は多くの理由で推奨されませんが、ほとんどの場合、Windows SDK ヘッダーを /Za オプションで #include できないためです。)

于 2013-10-31T03:19:31.933 に答える
2

あなたのコンパイラは標準に準拠していません (おそらくこれは文書化されたコンパイラ拡張機能ですか?)。GCC は次のエラーを返します。

main.cpp: In function 'int main()':
main.cpp:11:11: error: invalid initialization of non-const reference of type 'char&' from an rvalue of type 'char'
    f2(f1()); // error C2664. This is as expected.
        ^
main.cpp:2:6: error: in passing argument 1 of 'void f2(char&)'
void f2(char&);
    ^
main.cpp:12:12: error: invalid initialization of non-const reference of type 'A&' from an rvalue of type 'A'
    f4(f3()); // OK! Why???
            ^
main.cpp:7:6: error: in passing argument 1 of 'void f4(A&)'
void f4(A&);
于 2013-10-31T03:03:18.217 に答える