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
提交了错误报告答案 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&);