Chaining insersions to stream
The following code is a paired-down version of a something I've been
working with, adapted to a trivial example for the purposes of
illustration. In this model, as presented here, Factor is a class
that merely stores a multiplicative factor which can be incremented
and bound to a value using an overloaded function call operator
that takes the number to be multiplied as an argument.
The intent is that the function call operator returns an instance
of Value that encapsulates the number to be multiplied, together
with a reference to the factor itself. Only in the body of the
overloaded insertion operator is this factor applied, allowing (as
I had hoped) the kind of syntax that can be seen in its use in main.
#include <iostream>
using std::cout;
using std::ostream;
//---------------------------------------------------------------
struct Value;
//---------------------------------------------------------------
class Factor {
friend ostream& operator<< (ostream&, const Value&);
int f;
public:
explicit Factor(int ff): f(ff) { }
Value operator()(int = 1) const;
Factor& increment(int i) { f += i; return *this; }
};
//---------------------------------------------------------------
struct Value {
const Factor& factor;
int value;
Value(const Factor& fac, int val): factor(fac), value(val) { }
};
//---------------------------------------------------------------
Value Factor::operator ()(int val) const {
return Value(*this, val);
}
//---------------------------------------------------------------
ostream& operator<< (ostream& os, const Value& pr)
{
os << pr.value << " * " << pr.factor.f << " = "
<< pr.value * pr.factor.f;
return os;
}
//---------------------------------------------------------------
int main()
{
Factor fac(2);
cout << fac(5) << '\n' // expecting: 5 * 2 = 10
<< fac.increment(1)(5) << '\n' // expecting: 5 * 3 = 15
<< fac.increment(1)(5) << '\n'; // expecting: 5 * 4 = 20
return 0;
}
//---------------------------------------------------------------
In hindsight it shouldn't have come as any suprise that it did not
give me the output I had naively expected, but rather:
/**
* Output:
* 5 * 4 = 20
* 5 * 4 = 20
* 5 * 4 = 20
*/
but I'm wanting to get a clear understanding of exactly what's going
on here, if anyone can help.
I'm guessing that the chaining of the insertions to stream in a
single statement results in all three Value instances being
retrieved _before_ any actual output begins, and
then the fact that Value holds a _reference_ to the single Factor
instance would provide the sense behind what's happening.
Having said that, I would then expect that changing the ctor for
Value to take the Factor instance by value, and store it by value,
would solve the issue, but when I do that I get
/**
* Output:
* 5 * 4 = 20
* 5 * 4 = 20
* 5 * 3 = 15
*/
and now I am confused!
Regards PB
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]