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

13
我正在尝试在C++中完成这个任务。
class Abc
{
   int callFunction1()
};

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

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

在Visual Studio 2015中出现了“表达式必须是左值或函数设计者”的错误。我不明白哪里出错了。据我所知,&this的类型应该是Abc**对吗?

函数定义不是我的,所以我无法更改参数类型。


1
在什么情况下需要使用指向指针的指针?我认为大多数情况下这不是正确的方法。 - UnholySheep
1
“&this” 应该有类型 Abc** 对吧?它本应该有这样的类型,但是正如错误所说,“this”不是一个左值。你不能对它应用“&”。 - HolyBlackCat
7
一个简单的 auto p = this; function1(&p); 就可以工作。 - StoryTeller - Unslander Monica
2
是的,有。 - StoryTeller - Unslander Monica
@StoryTeller 对不起...谢谢!这太棒了! - disccip
显示剩余4条评论
3个回答

11
错误很明显。由于“this”不是左值,你不能取其地址。如果你只想要对象的地址,则只需传递“this”,而不是“&this”,并将函数声明更改为:
void function1(Abc* c1) //To just pass a pointer

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

auto temp = this;
function1(&temp);

如何工作:

  1. 由于thisprvalue,不能获取其地址,因此需要指向它的东西将其转换为lvalue,在这里是temp
  2. 现在temp指向this,取temp的地址将有效地取this的地址,尽管是间接的。
  3. 因此,由于您正在将lvalue的地址传递给function1,所以代码编译并按预期工作。

4
“错误很明显”这句话我不太同意,因为“lvalue”并不是一个常见词汇,如果没有更多的背景知识,错误就会变得晦涩难懂。这似乎有些无礼,因为它暗示了初学者应该通过阅读就能理解问题,我认为这并不合适。 - Adam Barnes

5

根据C++标准(9.2.2.1 The this pointer):

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

以及(5.3.1 一元运算符):

3 一元&运算符的结果是其操作数的指针。操作数必须是一个左值或qualified-id....

为了让它更清晰,请考虑以下代码片段。

例如,如果您有一个声明:

int x = 10;

那么您可能无法编写

int **p = &&x;

在正确的表达式中,&x 是一个 prvalue,根据标准的第二条引用,您不能将一元运算符 & 应用于 prvalue
你可以这样写:
int *q = &x;
int **p = &q;

因为 qlvalue


4
表达式 this 是一个右值,就像表达式 137'a' 一样,因此您无法获取它的地址。
如果您想获得指向 this 的指针的指针,您需要创建一个正确类型的新变量:
auto* ptr = this;
doSomething(&ptr);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接