Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do the "<<" and ">>" operators do I/O? [duplicate]

Tags:

c++

Possible Duplicate:
Operator overloading

I'm making a long awaited return to C++ and there's some basic notation that doesn't really seem to be that prominent in other languages.

If you look at this line of code

cout << "firstvalue is " << firstvalue << endl;

I realise what this does. It write's "firstvalue is x" to the console. x being the value of firstvalue. However, I do not know anything about the "<<" or ">>" double angled brackets. I haven't been able to research them or what they do as I don't know the formal name for them.

My question is, what actually happens (step by step) in the above statement? And what are these "<<" for? I think I understand that cout is a standard library function for writing to the console. However I'm used to either objective-c or dot notation. I do not see what object this "cout" function is a member of.

I can understand printf a little more easily, as at least it provides braces for the arguments. e.g. printf("your string here").

like image 612
Guy Joel McLean Avatar asked Oct 17 '12 16:10

Guy Joel McLean


People also ask

What is the use of << and >> in C++?

In case of std::cout , << is used to write to standard output. >> is not overloaded for std::cout . So std::cout >> x would give compilation error. In case of std::cin , >> is used to read from standard input. << is not overloaded for std::cin .

Is << used for input or output?

Input/Output Operator in C++ In C++, input and output (I/O) operators are used to take input and display output. The operator used for taking the input is known as the extraction or get from operator (>>), while the operator used for displaying the output is known as the insertion or put to operator (<<).

Can we overload << operator?

To get cout to accept a Date object after the insertion operator, overload the insertion operator to recognize an ostream object on the left and a Date on the right. The overloaded << operator function must then be declared as a friend of class Date so it can access the private data within a Date object.


2 Answers

C++ allows operator overloading. That means a user-defined type can define its own behavior on built-in operators. In this case the operators are called: left shift or right shift operators. Those operators have been traditionally been used for bit-shifting, but the standard library repurposes them to symbolize streaming operations.

You can find a list of the available operators in C and C++ here.

In your case you are streaming a string literal and a value of some type into std::cout, which is an object of type std::basic_ostream.

Step-by-Step

After precedence rules have been applied your code looks like this:

((cout << "foobar") << x) << endl;

The compiler will basically transform the object << object expressions into function calls.

operator<<(operator<<(operator<<(cout, "foobar"), x), endl);

Then it will figure out which overload to call. (This is really tricky. For now it should be sufficient to believe that it simply looks for an overload of operator<< with matching arguments).

Most of the built-in overloads for basic_ostream are here and here.

like image 149
pmr Avatar answered Sep 22 '22 17:09

pmr


The << operator is the "arithmetic left shift" in C++. For example:

3 << 2

evaluates to 12. The reason is that the binary representation of 3 is

00000011

shifting it twice to the left you get

00001100

and the numeric value of the result is 12.

What it has to do this with output? Nothing at all, actually. However in C++ you can redefine the meaning of operators thanks to overloading. The C++ standard library decided to redefine the meaning of the left-shift operator as sort of a "send-to-stream".

So what happens is that

std::cout << "whatever"

returns as value std::cout, but as side effect it outputs the string "whatever".

The operator was chosen because it had a reasonable precedence (overloading cannot change precedence, and you cannot define new operators) and the shape makes it appear somewhat "natural". Note however that the left-shift operator is just a normal operator and for example there is no guarantee about order of evaluation:

std::cout << f() << g() << h();

here the output will be the result of calling f(), followed by the result of calling g() and followed by the result of calling h()... but the functions themselves may be are called in a different order and for example h() could be called first!

So in a sense the "sequence look" of the operator is misleading, because it's about the sequence of output, but not about the sequence of evaluation.

like image 36
6502 Avatar answered Sep 25 '22 17:09

6502