为什么非常量引用参数可以绑定到临时对象
Why can a non-const reference parameter be bound to a temporary object?
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 到"字符 &"
我被告知,在C++中,非常量引用参数不能绑定到临时对象;在上面的代码中,f2(f1());
按预期触发错误。
但是,为什么相同的规则不适用于代码行f4(f3());
?
PS:我的编译器是VC++ 2013。即使我f2(f1());
注释该行,也包含f4(f3());
的代码将被编译而没有任何错误或警告。
更新:
MSDN 说:
在以前版本的 Visual C++ 中,非常量引用可以是 绑定到临时对象。现在,临时对象只能绑定 到常量引用。
所以我认为这是VC++的错误。我已向 VC++ 团队提交了错误报告
/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
在几种(非常受限的)情况下,启用语言扩展的编译器仍将允许非常量左值引用绑定到右值表达式。 我的理解是,这主要是为了避免破坏几个依赖这个"扩展"的巨大遗留代码库。
(通常,不建议使用/Za 的原因有很多,但主要是因为无法使用/Za 选项 #included Windows SDK 标头。
您的编译器不符合标准(也许这是记录的编译器扩展?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&);
permissive-(配置属性> C/C++> 所有选项>一致性模式)也禁用Microsoft语言扩展(根据 James McNellis 的答案),并将破坏不符合标准的代码。
此选项禁用宽松行为,并设置/Zc 编译器选项以实现严格一致性。
https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-160
作为参考,我使用的是Visual Studio 2019版本16.9.4并为v142平台工具集进行编译。
- 有没有办法将重载的类函数绑定到函数对象?
- Opengl 3/4 : 我可以将相同的缓冲区对象绑定到不同的目标吗?
- C++通过绑定到引用成员而缩短临时变量寿命?
- 未定义的对象(〔basic.life〕/8):为什么允许引用重新绑定(和常量修改)
- 对结构成员的临时绑定引用
- 为什么临时对象可以绑定到常量引用?
- 是否可以将匿名 lambda 函数绑定到对象以允许 lambda 中的代码访问对象的成员?
- 将临时对象绑定到常量引用
- C++17:是编译器为(静态存储持续时间)const引用绑定创建的可修改的临时对象(和存储)
- C++ const&绑定到临时对象
- 堆上是否会分配内存以支持临时对象到常量引用的嵌套绑定
- 将线程指针绑定到对象时错误
- OpenGL 纹理绑定到对象
- 正在返回临时对象并绑定到常量引用
- 为什么非常量引用参数可以绑定到临时对象
- 如何通过引用将函数绑定到对象
- BGL:我如何从一个绑定的对象到一个顶点描述符
- c++临时对象绑定到实参并返回const引用值
- 指定不绑定临时的"const int&"
- 将非常量引用绑定到临时对象 - 可能发生这种情况的示例