在获取此地址时,“表达式必须是l值或函数指示符”错误

时间:2017-09-20 19:56:26

标签: c++ this lvalue prvalue

我正在尝试用C ++做到这一点:

class Abc
{
   int callFunction1()
};

void function1(Abc** c1) {//do something}

int Abc::callFunction1()
{
   function1(&this);
   return 0;
}

我在visual studio 2015中得到“表达式必须是l值或函数指示符”错误。所以我不明白我哪里出错了。据我所知,&this应该有Abc**类型的权利吗?

功能定义不是我要改变的。所以我不能只改变参数类型。

3 个答案:

答案 0 :(得分:8)

错误很清楚。由于this不是左值,因此您无法获取其地址。如果您只想要对象的地址,那么只需传递this,而不是&this,并将函数声明更改为:

void function1(Abc* c1) //To just pass a pointer

但是,既然你提到你不能改变函数的定义,你可以创建一个临时变量并传递它的地址:

auto temp = this;
function1(&temp);

这是如何运作的:

  1. 由于thisprvalue且无法获取其地址,因此您需要指向它以将其转换为左值,此处为temp
  2. 现在temp指向this,取temp的地址将有效地获取this的地址,尽管是间接的。
  3. 因此,由于您将左值的地址传递给function1,因此代码会按预期编译并运行。

答案 1 :(得分:4)

表达式this是一个右值,与表达式137'a'相同,因此您无法获取其地址。

如果你想获得指向this的指针,你需要创建一个正确类型的新变量:

auto* ptr = this;
doSomething(&ptr);

答案 2 :(得分:3)

来自C ++标准(9.2.2.1 The this pointer)

  

1在非静态(9.2.1)成员函数的主体中,关键字   这是一个prvalue表达式,其值是地址   调用该函数的对象。

和(5.3.1一元运算符)

  

3一元&的结果operator是指向其操作数的指针。的的   操作数应为左值或限定ID ....

要更清楚地考虑以下代码段。

例如,如果您有声明

    os.rename(filename, '1000-%02d.tiff' % i)
    i += 1

然后你可能不会写

int x = 10;

在正确的表达式中int **p = &&x; &x,根据标准的第二个引用,您可能不会将一元运算符prvalue应用于&

你可以写

prvalue

因为int *q = &x; int **p = &q; q