I'm trying to do this in C++:
class Abc
{
int callFunction1()
};
void function1(Abc** c1) {//do something}
int Abc::callFunction1()
{
function1(&this);
return 0;
}
And I get "expression must be an l-value or function designator" error in visual studio 2015. So I don't understand where I go wrong. To my knowledge, &this
should have the type Abc**
right?
The function definition isn't mine to change. So I can't just change the parameter type.
The error is clear enough. Since this
is not an lvalue, you cannot take its address. If you just want the address of the object, then just pass this
, not &this
, and change the function declaration to:
void function1(Abc* c1) //To just pass a pointer
However, since you mentioned you cannot change the definition of the function, you can create a temporary variable and pass its address:
auto temp = this;
function1(&temp);
How this works:
this
is a prvalue and cannot have its address taken, you need something to point to it to turn it into an lvalue, here temp
.temp
points to this
, taking temp
's address will effectively take this
's address, albeit indirectly.function1
, the code compiles and works as expected.From the C++ Standard (9.2.2.1 The this pointer)
1 In the body of a non-static (9.2.1) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called.
and (5.3.1 Unary operators)
3 The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id....
To make it more clear consider the following code snippet.
If for example you have a declaration
int x = 10;
then you may not write
int **p = &&x;
In the right expression &x
is a prvalue
and according to the second quote from the Standard you may not apply the unary operator &
to the prvalue
.
You could write
int *q = &x;
int **p = &q;
because q
is lvalue
.
The expression this
is an rvalue, the same way that the expressions 137
or 'a'
are, and so you can't take its address.
If you want to get a pointer to a pointer to this
, you'll need to create a new variable of the right type:
auto* ptr = this;
doSomething(&ptr);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With