#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());“输出时,我将得到错误:左值需要作为一元'&'操作数。但是如何获取 (v.开始())的地址? 运算符与函数不一样吗?
4条答案
按热度按时间vbopmzt11#
函数
f
返回int类型的临时对象不能将操作员地址应用于临时对象。
您可以返回一个对动态创建的对象的引用,例如
在本例中,
printf
的调用如下所示都是正确的。
对于这个表达式
&(*(v.begin()))
,解引用操作符通过迭代器返回指向对象的引用。piwo6bdm2#
我无法获取f()的地址,如果我注解"printf(" % p\n ",& f());"输出时,我将得到错误:需要左值作为一元"&"操作数
我们不能取
f()
的地址,因为f
返回by value,这意味着表达式f()
是int
类型的右值,它不可能是&
的操作数,因为运算符&
需要一个 * 左值 * 操作数,而f()
不需要,这正是错误所说的。如何获取 *(v.begin())地址?
另一方面,
std::vector::begin
返回一个迭代器到向量的第一个元素(如果vector非空),然后在v.begin()
上应用*
得到第一个元素本身(即*(v.begin())
是一个左值),我们可以取其地址。az31mfrm3#
正如注解中提到的,解引用interators返回一个 reference,即类似于指针的结构(从技术上讲,是在引擎盖下面)-现在您可以获取
*v.begin()
的地址(你不需要括号,.
比*
有更高的优先级)因为获取引用的地址意味着获取被引用对象的地址,这里是向量的第一个int
,这和取一个普通对象的地址,或者数组中第一个元素的地址是一样的,就好像,在f
中,你取了&a[0]
.另一方面,
f
本身返回一个 value -这只是一个没有有效地址的临时对象(潜在地至少-根据调用约定,该值可以在堆栈上返回,那么它确实具有地址,但是也在CPU寄存器中,那么就没有地址了)。这个值首先需要赋给一个变量,这样你就可以取的地址了。egdjgwm84#
实际上
v.begin()
返回rvalue iterator
,所以&v.begin()
将不起作用。但是itirator
*v.begin()
的解引用操作符返回const int&
,而const int&
又是lvalue
引用,允许在其上调用addressof
。