The value enh::setw(26);
is an rvalue . Actually, temporaries like that are rvalues. Rvalues have special properties. One of them is that their address can't be taken (&enh::setw(26);
is illegal), and they can't generally bind to references to non-const (some temporaries can bind to references to non-const, but these undergo special rules: Calling member functions on temporary objects and catching exception objects by reference to non-const. In the latter case, the temporary even is an lvalue).
There are two kind of expressions: lvalues that denote objects (that in turn may store an value) or functions, and rvalues which are meant to represent values read out of an object or represented by temporaries, numeral literals and enumerator constants. In C++03, to be able to pass such values to a function that accepts its value by-reference, there is a rule that they can be accepted by reference-to-const: setw const& p
would accept it. That is, you would have to declare your operator like this:
EnhSimOutput& operator<< (setw const& p);
That's a bit unfortunate, because you can't disambiguate constant lvalues (objects you created on the stack using const enh::setw e(26);
for example) and non-const or const rvalues (like enh::setw(26);
which is a non-const temporary). Also, if you go by that, the parameter can't have called non-const member functions on it, because it's a reference-to-const. For that reason, C++1x, the next C++ version, introduce a new kind of reference, so-called rvalue-references which fixes that.
The Microsoft Visual C++ compiler binds rvalues to references to non-const, but gives out a warning when doing that (you have to use at least warning level 4 for it to show up). That's unfortunate, because problems rise up when porting to other compilers that are more strict in Standard compliance.