Возвращаемое значение функции, не распознанной как lvalue

Вот пример:

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;
}

Я могу исправить это, используя boo::getZ(), возвращающую ссылку на указатель, но я пытаюсь понять, в чем разница между двумя параметрами, передаваемыми в foo(). Int*, возвращаемое boo::getZ(), не является lvalue? Если так, то почему бы и нет?

2 ответа

Решение

Если T это тип объекта и f объявлен как...

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

Так getZ() это prvalue (T = int *), которая является значением, а не значением.

"Это int* возвращается boo::getZ() не lvalue? Если так, то почему бы и нет?

Нет, подумай дважды! Возвращаемое значение функции prvalue если ссылка не возвращается.

Тебе нужно

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

правильно скомпилировать.

Хотя имея что-то вроде

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

private:
   int z;  
};

чувствует себя лучше для меня (хотя не правильно, наконец, ИМХО).


То, что я имел бы для реального обеспечения функций-членов getter / setter, выглядело бы следующим образом (обратите внимание, это псевдокод, замени T с актуальными типами данных, которые вам нужны!)

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

private:
   T z_;  
};
Другие вопросы по тегам