"выражение должно быть l-значением или указателем функции" при получении адреса этого

Я пытаюсь сделать это в C++:

class Abc
{
   int callFunction1()
};

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

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

И я получаю ошибку "выражение должно быть l-значением или обозначением функции" в visual studio 2015. Поэтому я не понимаю, где я ошибаюсь. Насколько мне известно, &this должен иметь тип Abc** право?

Определение функции не мое, чтобы изменить. Поэтому я не могу просто изменить тип параметра.

3 ответа

Решение

Ошибка достаточно понятна. поскольку this не является lvalue, вы не можете взять его адрес. Если вы просто хотите адрес объекта, то просто передайте this не &this и измените объявление функции на:

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

Однако, поскольку вы упомянули, что вы не можете изменить определение функции, вы можете создать временную переменную и передать ее адрес:

auto temp = this;
function1(&temp);

Как это работает:

  1. поскольку this является prvalue и не может быть взят его адрес, вам нужно что-то, чтобы указать на него, чтобы превратить его в lvalue, здесь temp,
  2. Теперь, когда temp указывает на this, принимая temp адрес будет эффективно this адрес, пусть и косвенный.
  3. Поэтому, так как вы передаете адрес lvalue function1 код компилируется и работает как положено.

Из стандарта C++ (9.2.2.1 Указатель this)

1 В теле нестатической (9.2.1) функции-члена ключевое слово this является выражением prvalue, значением которого является адрес объекта, для которого вызывается функция.

и (5.3.1 унарные операторы)

3 Результатом унарного оператора & является указатель на его операнд. Операнд должен быть lvalue или квалифицированным идентификатором....

Для большей ясности рассмотрим следующий фрагмент кода.

Если, например, у вас есть декларация

int x = 10;

тогда ты не можешь писать

int **p = &&x;

В правильном выражении &x это prvalue и согласно второй цитате из Стандарта вы не можете применять унарный оператор & к prvalue,

Вы могли бы написать

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

так как q является lvalue,

Выражение this это значение, так же, как выражения 137 или же 'a' есть, и поэтому вы не можете взять его адрес.

Если вы хотите получить указатель на указатель на thisвам нужно будет создать новую переменную правильного типа:

auto* ptr = this;
doSomething(&ptr);
Другие вопросы по тегам