user3827224
user3827224

Reputation: 53

Return value of a function not recognized as lvalue

Here's an example:

void foo(int*& x) {}

struct boo  
{  
  int* z;  
  int* getZ() { return z; }  
};

int main()
{
  int* y;
  foo(y);  // Fine

  boo myBoo;
  foo(myBoo.getZ());  // Won't compile

  return 0;
}

I can fix this by having boo::getZ() return a reference to a pointer, but I'm trying to understand what the difference is between the two parameters being passed in to foo(). Is the int* being returned by boo::getZ() not an lvalue? If so, why not?

Upvotes: 2

Views: 712

Answers (2)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

"Is the int* being returned by boo::getZ() not an lvalue? If so, why not?"

No, think twice! The return value of a function is a prvalue unless a reference is returned.

You need

struct boo {  
   int* z;  
   int& getZ() { return *z; }
   // ^ 
   // |------------- Note the reference '&'
};

to compile this correctly.

Though having something like

struct boo {  
   int& getZ() { return z; }

private:
   int z;  
};

feels better for me (though not right finally IMHO).


What I'd have for really providing getter/setter member functions, would look as follows (Note it's pseudo code, replace T with the actual data types you need!)

class boo {  
public:
   T z() const { return z_; }
   void z(const T& newValue ) { z_ = newValue; }

private:
   T z_;  
};

Upvotes: 2

Kerrek SB
Kerrek SB

Reputation: 476990

If T is an object type and f is declared as...

T &  f();                                          f() is an lvalue
T && f();                     then                 f() is an xvalue
T    f();                                          f() is a prvalue

So getZ() is a prvalue (T = int *), which is an rvalue, and not an lvalue.

Upvotes: 9

Related Questions