C++ 左值引用
Posted
技术标签:
【中文标题】C++ 左值引用【英文标题】:C++ lvalue references 【发布时间】:2020-05-17 15:33:25 【问题描述】:所以最近我重新访问了类型声明的引用,但我不太了解它们。
考虑一下这个伪代码:
int ia = 10;
int& ref = ia;
现在,我的问题是:
-
这些
int& ref
如何在内部工作,这是否意味着ref
的地址被分配了ia
的地址,因此等于&ia
如果不是那么编译器在看到这些引用时会做什么?
为什么这些引用不在 c++ 程序中编译?
【问题讨论】:
【参考方案1】:您根本不必考虑地址。 ref
只是 ia
的另一个名称,或者换句话说,ref
是 ia
的别名。只是代码的语法糖。
这种情况下的编译器根本不需要做太多,只要跟踪代码何时包含ref
,将其替换为ia
即可。
【讨论】:
感谢您的回复,但我想知道这是如何在内部工作的。编译器看到这个会做什么? @Alex • C++ 标准没有规定编译器在内部做什么。我的编译器尽可能消除引用,并将其视为只是对所引用对象的别名替换。 @Alex,一般来说,您会尽可能避免使用宏。 @Alex,处理器使用宏的定义对您的源代码执行搜索替换,然后编译最终结果(编译步骤中没有宏)。所以如果你有#define MY_CONSTANT 2
和int a = MY_CONSTANT;
这样的东西,那么对于编译器来说它就是int a = 2;
。这是一个您不想使用宏的示例,因为 const
和 constexpr
更适合这样的用例。现在正确使用宏仅限于少数情况,您经常可以看到它们用于创建单元测试。
@Alex 您通常将它们用于更复杂的表达式或作为函数参数。【参考方案2】:
C++ 标准没有指定编译器应该如何实现引用。很多人认为它们只是别名,但实际上,它们只是实现为 const
指针。
C++ 引用实际上是 const
指针。所以:
int ia = 10;
int& ref = ia;
ref++; // ia is 11 now
可能会被编译器转换为:
int ia = 10;
int* const ref = ia;
(*ref)++; // ia is 11 now
它们需要初始化,因为必须初始化常量。
【讨论】:
在大多数情况下这是错误的,例如参见godbolt.org/z/TA8tkN。 这不是假的。尝试使用 -00。并松开iostream
以获得更清晰的输出。另见:godbolt.org/z/xEQVXe,请查看此线程:twitter.com/tvaneerd/status/1252653227885178882?s=20
如果你松开了ostream,代码就是一个noop,O0在这里更像是AST的反映,而不是引用的语义。
O0
是编译器在调试模式下生成的实际程序集。在不同的情况下,编译器可能无法将其优化为简单的赋值。以上是关于C++ 左值引用的主要内容,如果未能解决你的问题,请参考以下文章