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 的另一个名称,或者换句话说,refia 的别名。只是代码的语法糖。

这种情况下的编译器根本不需要做太多,只要跟踪代码何时包含ref,将其替换为ia即可。

【讨论】:

感谢您的回复,但我想知道这是如何在内部工作的。编译器看到这个会做什么? @Alex • C++ 标准没有规定编译器在内部做什么。我的编译器尽可能消除引用,并将其视为只是对所引用对象的别名替换。 @Alex,一般来说,您会尽可能避免使用宏。 @Alex,处理器使用宏的定义对您的源代码执行搜索替换,然后编译最终结果(编译步骤中没有宏)。所以如果你有#define MY_CONSTANT 2int a = MY_CONSTANT; 这样的东西,那么对于编译器来说它就是int a = 2;。这是一个您不想使用宏的示例,因为 constconstexpr 更适合这样的用例。现在正确使用宏仅限于少数情况,您经常可以看到它们用于创建单元测试。 @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++ 左值引用的主要内容,如果未能解决你的问题,请参考以下文章

C++的左值 右值 左值引用 右值引用 大白话总结

C++左值引用和右值引用

c++中的左值和右值,右值引用到底是啥?关于引用这一节看得很迷糊。

C++ 左值引用

7. C++左值引用和右值引用

C++ 引用做左值