Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does operator chaining happen in C++?

Tags:

c++

I have a totally basic C++ question here.

#include <iostream>
using namespace std;

int main() {
    int a = 255;
    cout << hex << a << endl; // <-----
}

In the code piece above, how is the std::cout statement chained?

I understand that an implementation of cout would return the reference to cout object to allow chaining to happen, so it should be executed as:

(((cout << hex) << a) << endl)

i.e. equivalent to these, in order

  1. cout << hex
  2. cout << a
  3. cout << endl

But this cannot be the case because somehow value of a needs to be converted to hex form!

How are operators actually chained by the compiler to make the conversion happen?

like image 461
Lazer Avatar asked Mar 04 '12 14:03

Lazer


2 Answers

You've got it right, that's exactly how it works. hex just has a special type that changes the internal state of the cout object when passed to its operator<< function. The internal state then determines how any future values passed to cout via operator<< are treated.

std::hex happens to be a function. cout << hex doesn't call the hex function as such, however: it passes a pointer to the hex function to an operator<< overload for ostream which accepts function pointers with a particular signature. hex() is then called from inside the operator implementation via that function pointer, and modifies the ostream object from there as far as I know.

like image 51
pmdj Avatar answered Nov 18 '22 15:11

pmdj


Here is how hex is usually implemented:

inline ios_base&
hex(ios_base& __base)
{
    __base.setf(ios_base::hex, ios_base::basefield);
    return __base;
}

As you can see, hex does not perform any conversion by itself: instead, it sets an option in the base stream to use hex for printing of numbers passed into it at a later point.

EDIT (in response to a comment)

As hammar correctly notes, the other part of the puzzle is how hex(ios_base& __base) is being called. There is an overload of the << operator with this signature:

ostream& operator <<(ostream& (*)(ostream&))

This overload is essential implementation detail of stream manipulators. It is this overload that calls hex, and lets it do its "magic" (which of course should not sound like magic to you any longer).

like image 8
Sergey Kalinichenko Avatar answered Nov 18 '22 15:11

Sergey Kalinichenko