On 07/05/2007 12:59 PM, Andy Ross wrote:

References can be lvalues, so it's possible to write functions whose
returned valued can be assigned.

True.

The examples are usually pretty
academic, but consider a sparse 2D array with a method like

  int& element(int x, int y);

You can use this thing as element(3, 4) to get the value, but you can
also use:

  array->element(3, 4) = 12345;

to *set* the value. Cute, huh? And utterly worthless.

Agreed.  That example is academic and not a high-value item.

OTOH, the existence of a straw man does not preclude the
existence of somewhat more worthwhile instances.

I've seen code where lvalue-valued functions were put to
good use.  In one case that springs to mind, the actual
application was more complicated, but an easy way to
appreciate the idea is:

 Group(xx, yy) = some->list;

I'm sure some people will take this as evidence of my perversely
incompetent programming technique ... except that I didn't write
the code in question.  It was designed by two of my friends, each
of whom had recently served as a representative to the ISO C++
standardization committee.

Attached is a simplified, somewhat academic example to illustrate
what I'm talking about.


/////////////
// list-to-elements
//

#ifdef DOCUMENTATION
Objective:  We want to assign:
  Group(xx, yy) = foo;

where the RHS is a two-element list; we want the first element of the
list to be assigned to xx, and the second element of the list to be
assigned to yy.  We want to do this in one statement, so that nothing
needs to be recomputed (or stored by the creature on the RHS), to make
it manifestly thread-safe.

We do not want to require any predeclared relationship between xx and
yy; we just put them together on the fly.

This sort of list-to-elements assignment is routine and natural
in perl.  There are several ways of doing it in C++.
This way is reasonably convenient.

#endif /* DOCUMENTATION */

using namespace std;
#include <iostream>
#include <list>

typedef list<int> LI;

class Group {
  int* xptr;
  int* yptr;
public:

// no default constructor:
  Group();

// Constructor using two ints:
  inline Group(int& xx, int& yy){
    xptr = &xx;
    yptr = &yy;
  }

// Assignment operator, assigning from a list:
  inline const LI& operator= (const LI& _rhs) {
    LI rhs(_rhs);
    if (rhs.size() > 0) {
      *xptr = rhs.front(); 
      rhs.pop_front();
    }
    if (rhs.size() > 0){
      *yptr = rhs.front(); 
      rhs.pop_front();
    }
    return _rhs;
  }
};


int main(){
  LI foo;
  foo.push_back(123);
  foo.push_back(456);
  int xx(1);
  int yy(2);
  Group(xx, yy) = foo;
  cout << xx << ", " << yy << endl;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to