"выражение должно быть 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);
Как это работает:
- поскольку
this
является prvalue и не может быть взят его адрес, вам нужно что-то, чтобы указать на него, чтобы превратить его в lvalue, здесьtemp
, - Теперь, когда
temp
указывает наthis
, принимаяtemp
адрес будет эффективноthis
адрес, пусть и косвенный. - Поэтому, так как вы передаете адрес 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);