为何能取std::vector的*v.begin()地址却无法取函数返回值的地址?
#include <vector> #include <cstdio> using namespace std; int f() { int* a = new int(3); return *a; } int main() { //printf("%p\n", &f()); vector<int> v{3}; printf("%p\n", &(*(v.begin()))); }
问题
我无法对f()的返回值取地址,取消printf("%p\n", &f());的注释后会报错“lvalue required as unary ‘&’ operand”。但为何可以对*(v.begin())取地址?难道*运算符的行为和函数返回值不一样吗?
解答
核心差异在于左值和右值的本质区别:
函数
f()的返回类型是int(非引用类型),返回的是一个临时右值。虽然函数内部*a是左值,但return *a会把这个值拷贝成临时对象返回给调用者——这个临时对象没有持久的内存地址,C++标准明确禁止对右值取地址,因此&f()会触发编译错误。vector的begin()返回迭代器,迭代器的operator*()(即*(v.begin()))返回的是容器元素的左值引用(int&)。这个引用指向vector容器内存中真实存储的元素,是有持久生命周期的左值,左值本身对应一块固定的内存空间,自然可以用&取地址,&(*(v.begin()))拿到的就是v中第一个元素的内存地址。
简单总结:函数返回非引用类型时给你的是临时拷贝(右值),迭代器解引用给你的是容器内真实元素的引用(左值),这就是两者的本质区别。
内容的提问来源于stack exchange,提问作者xiutao
相关产品推荐
相关产品推荐

