为什么非const引用参数可以绑定到临时对象?

时间:2013-10-31 02:46:58

标签: c++ reference const object-lifetime temporary-objects

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&)':无法从'char'转换参数1   到'char&'

我被教导过,在C ++中,非const引用参数不能绑定到临时对象;在上面的代码中,f2(f1());会按预期触发错误。

但是,为什么同样的规则不适用于代码行f4(f3());

PS:我的编译器是VC ++ 2013.即使我对行f2(f1());发表评论,也会编译包含f4(f3());的代码而不会出现任何错误或警告。

更新

MSDN说:

  

在以前的Visual C ++版本中,非const引用可能是   绑定到临时对象。现在,临时对象只能绑定   到const引用。

所以我认为这是VC ++的一个错误。我已向VC++ team

提交了错误报告

2 个答案:

答案 0 :(得分:4)

如果使用the /Za option进行编译以禁用语言扩展,则编译器会拒绝两个调用:

> 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左值引用绑定到rvalue表达式。我的理解是,这主要是为了避免破坏依赖于这种“扩展”的几个巨大遗留代码库。

(一般情况下,建议不要使用/ Za,原因很多,但主要是因为Windows SDK标题不能与/ Za选项一起使用#。

答案 1 :(得分: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&);