c++ 为什么我可以取 *v.开始()的地址,其中v是一个std::vector

xwbd5t1u  于 2023-02-17  发布在  其他
关注(0)|答案(4)|浏览(101)
#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.开始())的地址? 运算符与函数不一样吗?

vbopmzt1

vbopmzt11#

函数f返回int类型的临时对象

int f()
{
    int* a = new int(3);
    return *a;
}

不能将操作员地址应用于临时对象。
您可以返回一个对动态创建的对象的引用,例如

int & f()
{
    int* a = new int(3);
    return *a;
}

在本例中,printf的调用如下所示

printf("%p\n", ( void * )&f());

都是正确的。
对于这个表达式&(*(v.begin())),解引用操作符通过迭代器返回指向对象的引用。

piwo6bdm

piwo6bdm2#

我无法获取f()的地址,如果我注解"printf(" % p\n ",& f());"输出时,我将得到错误:需要左值作为一元"&"操作数
我们不能取f()的地址,因为f返回by value,这意味着表达式f()int类型的右值,它不可能是&的操作数,因为运算符&需要一个 * 左值 * 操作数,而f()不需要,这正是错误所说的。
如何获取 *(v.begin())地址?
另一方面,std::vector::begin返回一个迭代器到向量的第一个元素(如果vector非空),然后在v.begin()上应用*得到第一个元素本身(即*(v.begin())是一个左值),我们可以取其地址。

az31mfrm

az31mfrm3#

正如注解中提到的,解引用interators返回一个 reference,即类似于指针的结构(从技术上讲,是在引擎盖下面)-现在您可以获取*v.begin()的地址(你不需要括号,.*有更高的优先级)因为获取引用的地址意味着获取被引用对象的地址,这里是向量的第一个int,这和取一个普通对象的地址,或者数组中第一个元素的地址是一样的,就好像,在f中,你取了&a[0].
另一方面,f本身返回一个 value -这只是一个没有有效地址的临时对象(潜在地至少-根据调用约定,该值可以在堆栈上返回,那么它确实具有地址,但是也在CPU寄存器中,那么就没有地址了)。这个值首先需要赋给一个变量,这样你就可以取的地址了。

egdjgwm8

egdjgwm84#

实际上v.begin()返回rvalue iterator,所以&v.begin()将不起作用。但是itirator*v.begin()的解引用操作符返回const int&,而const int&又是lvalue引用,允许在其上调用addressof

相关问题