Streaming and member function operator precedence

Hi all,

I've recently had some issues with the streaming operator and the
order of precedence used when mixing it with the member function
operator (operator .) Example code is below.

*************************************************************************
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <vector>
using namespace std;

class A
{
   public:
       A() : i(0) {};
       int f() {
           i++;
           v.push_back(i);
           return i;
       }

       void reset() { i = 0; v.clear(); }

       int i;
       vector<int> v;
};

int main()
{
   A a;

   // Order of action:
   // - Member functions fire from RIGHT to LEFT.
   // - Insertion operators fire from LEFT to RIGHT
   cout << a.f() << a.f();
   cout << endl;

   cout << "Vector contents a: ";
   for (unsigned int i = 0; i < a.v.size(); ++i )
   {
       cout << a.v.at(i);
   }
   cout << endl;

   a.reset();
   int k;
   // Order of action;
   // - Member functions fire from LEFT to RIGHT
   // - Addition operator fires.
   // - Assignment operator fires.
   k = a.f() + 3*a.f();
   cout << "k: " << k << endl;
   cout << "Vector contents a: ";
   for (unsigned int i = 0; i < a.v.size(); ++i )
   {
       cout << a.v.at(i);
   }
   return 0;
}

*********************************************************************************
OUTPUT:
21
Vector contents a: 12
k: 7
Vector contents a: 12
*********************************************************************************

The result of this seems to indicate that the . operator for the
member function call has different associativities in the different
situations. I must be missing something here, but I haven't been able
to find anyone to give me a conclusive answer on it. Can anyone here
shed some light on it?

Cheers,
Daniel.
The problem is not about member function, it is about cout!!!
here is the cout code:
 
	cout << a.f() << a.f() << a.f();                              


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	_Myt& __CLR_OR_THIS_CALL operator<<(int _Val)
		{	// insert an int
		ios_base::iostate _State = ios_base::goodbit;
		const sentry _Ok(*this);

		if (_Ok)
			{	// state okay, use facet to insert
			const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput);
			ios_base::fmtflags _Bfl =
				ios_base::flags() & ios_base::basefield;
			long _Tmp = (_Bfl == ios_base::oct
				|| _Bfl == ios_base::hex)
				? (long)(unsigned int)_Val : (long)_Val;

			_TRY_IO_BEGIN
			if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this,
				_Myios::fill(), _Tmp).failed())
				_State |= ios_base::badbit;
			_CATCH_IO_END
			}

		_Myios::setstate(_State);
		return (*this);                                                                                
		}

cout first calculates all expression values, it means cout calculates, ahead 3 times the a.f() function, and then prints out, after 3 times calculated a.f() returns 3, then cout back one step up,then shows 2, ... 1,

When using cout with objects, i recomment using like this:
1
2
3
4
	cout << a.f();                            
	cout<< a.f();
	cout<< a.f();
Last edited on
Aye, Im looking at having to do that. But I'm still curious. Can't work out why it backs up in reverse order in this case:
 
cout << a.f() << a.f();

but not for this case:
 
cout << a.f() + 3*a.f();

Topic archived. No new replies allowed.