This question already has answers here:
Closed 10 years ago.
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").
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.
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.
C++17 update
In C++17 this design bug was fixed by special casing << operator to ensure left-to-right evaluation. After C++17 in the expression std::cout << f() << g(); f must be called before g.
The << is an operator, the same way + is an operator and * is an operator. In the way the following are equivalent expressions:
5 + 3 + 2
((5 + 3) + 2)
So are the next two:
std::cout << "Hello" << std::endl
((std::cout << "Hello") << std::endl)
It's just an operator with two operands. For the fundamental types, the << and >> operators are actually known as the left and right shift operators. They perform bitwise shifting. For example, 5 << 1 will shift all the bits in 5 (0101) left one place, to get 10 (1010).
However, as with most other operators, you can overload the shift operators. In the case of the input/output library, the shift operators are overloaded to provide a natural syntax for input and output to a stream. That's because the directionality of the << and >> tokens look like something is flowing one way or the other. With these I/O classes, these operator overloads return a reference to the stream you're performing the operator on so that they can be chained together.
You can overload the shift operators for a particular class by either providing a member function operator<< or operator>> that takes one argument (the operand to the right of the operator). Alternatively, you can provide non-member function with the same names that take two arguments, the two operands of the operator respectively.
They're referred to as stream insertion (or extraction, in the case of istream >>), and are actually a semantic overload of the left-shift and right-shift operators.
So, this:
int x = 1 << 1;
is a bit shift, but this:
std::cout << x;
is a stream insertion. You can write it out explicitly as:
operator <<(std::cout, x);
and get exactly the same result. The conventional format of stream insertion operators (they can be overloaded for user-defined types, so it's not unusual to write your own) is
std::ostream& operator <<(std::ostream&, T value);
The output stream is returned (by reference) so you can chain calls: your example translates as:
operator<< (
operator<< (
operator<<(std::cout, "firstvalue"),
firstvalue
),
std::endl
);
Oh, and ... std::cout (and std::cerr etc.) are not functions: they're global objects. The function here is the overloaded << operator. Think of them as FILE *stdout, *stderr equivalents.
There are some advantages of C++ iostreams over printf et. al:
type-safety: you can't mistakenly print an integer with "%f" and get garbage, because overload resolution automatically selects the std::ostream& operator<<(std::ostream&, double) function at compile time
support for user-defined types: you can write a stream insertion operator for your whizzy new class, and it will just work, everywhere
stream abstraction: you can use the same overloads (so you only write them once) to format to stdout and stderr (cout/cerr), and files (std::ofstream) and strings (std::ostringstream). There's no need to handle printf/fprintf/snprintf separately.
There are also some disadvantages:
performance: there is some penalty to all that abstraction, and the generality of the locale system which is configured at runtime
verbosity: at least for primitive types already supported by printf, the format strings are much terser and more expressive
It's syntactic sugar for the following:
// Let the function 'print' be a renaming of 'operator<<'
// with T being the type of the object you want to print.
std::ostream& print(std::ostream&, const T&);
// 1) Print "first value is" and then return the stream you
// to which to just printed (ie. cout). 2) Use the returned
// stream to chain function calls and print 'firstValue'.
print(print(std::cout, "first value is"), firstValue);
Related
Here's my simple code:
int main()
{
int x = 5;
cout << (x++) << endl;
return 0;
}
the code above prints 5, not 6, even with the parenthesis, My thought is x = x + 1 be executed first before it is printed out? can anyone explain to me what's going on here? Thank you
edit: i definitely understand ++x guys, my question is about change operator precedence using ()
i definitely understand ++x guys, my question is about change operator precedence using ()
Operator precedence has nothing to do with this.
The misunderstanding probably isn't your fault: you've likely been mistaught. Your teacher(s) told you that an operand with a higher precedence, than some other operand, will be "executed first".
While this is a common explanation in schools, it is not true.
There are three things that can change the meaning of an expression in this sense:
Operator precedence
This is merely a set of rules that tell us, and tell the compiler, which operands go to which operator. Like, in 3 + 5 * 7, do we pass 3+5 to the multiplication operator, or do we pass 5*7 to the addition operator? It's about parsing.
Evaluation order
Each operand then needs to be evaluated to produce a value (e.g. 3+5 becomes 8, or 5*7 becomes 35). The rules on the order in which these evaluations happen are quite complicated in C++, more so than you might expect, but you usually don't have to worry about them unless you're doing crazy things in between sequence points (to borrow pre-C++11 parlance).
(This is the closest you'll get to a notion of "will be executed first".)
The meaning of the operator
This is where you're coming unstuck here. The meaning of the postfix increment operator x++ is "increment x, and evaluate to the old value". Period. Full stop.
It doesn't matter which operator precedence rules led to the expression x++ being evaluated (as opposed to some other interpretation of the symbols in your code): when it's evaluated, whenever it's evaluated, you get the old value for x.
The meaning of the prefix increment operator ++x, however, is "increment x, and evaluate to the new value", and that's the behaviour you want, so that's the code you should write.
Ultimately, what sequence of computer instructions actually produces this behaviour is completely up to the compiler, and can be surprising. You shouldn't worry about it, as long as the program's result is as specified in the standard.
So just forget about this "will be executed first" stuff; it's rubbish.
The expression (x++), with or without parentheses, evaluates to the previous value of x, and has the side-effect of increasing x.
If you want to see the effect of the increase then use the obscure
cout << (x++, x) << endl;
The value of x++ is the value of x before incrementing, no matter how many brackets you put. This has nothing to do with operator precendence, but this is just how post increment is defined.
edit: i definitely understand ++x guys, my question is about change operator precedence using ()
I already mentioned it, but to be clear: The value you see has little to do with operator precedence. With or without brackets ++ comes before <<. Even if this wasnt the case it would not change the value you get from x++. You could change order of the operators if you wrote
(cout << x)++ << endl;
but that would try to call ++ on the stream...
This is because x++ evaluates the value of x (5 in your case) and will increase its value after that....
what you are looking for is the pre-increment, also ++x
That is because, it is unrelated to operator precedence. The post-increment operator ++, as opposed to the pre-increment operator, increments its operand after its evaluation.
So what you see is normal and that behavior cannot be changed by introducing enclosing parenthesis around the variable. If you want the opposite to happen, then you should use the pre-increment operator like the following:
cout << ++x << endl;
I know () has higher precedence than <<, and << has higher precedence than ==, but I want to know why I can't write cout<<a==b; yet can write cout<<(a==b); in C++.
How the compiler translates cout<<a==b; and then shows error?
<< has higher precedence than ==
as you can see here.
The statement
cout<<a==b
is equivalent to
(cout<<a)==b
The expression
cout<<a
returns a stream. This stream is compared to b. If there is no left shift operator for a stream and a or no comparing operator for a stream and b this causes a compiler error
cout<<a==b is similar to (cout<<a) == b as << has higher precedence over ==. Now cout<<a will be syntactically incorrect if the type of a is not supported for <<. Next, if a has an overload for the << operator, it will again be syntactically wrong as the == operator can't operate with std::stream and type of b unless b overloads this compare operator.
But in case of cout<<(a==b), a==b will result in a boolean value. As the << operator support boolean value it is a valid operation.
<< priority is higher than == so it's interpreted as (cout<<a)==b
but = has lower so you can do :
bool t = a == b
After debugging I found that ternary operator ?: does not have priority. My question is why?
I have the following code:
bool T = true;
cout << ((T == true) ? "true" : "false") << endl;
cout << (T == true) ? "true" : "false";
Output:
true
1
live demo: http://ideone.com/Tkvt9q
The conditional operator does have a precedence (albeit slightly complicated by its ternary nature); but that precedence is very low. Since it's lower than <<, the second is parsed as
(cout << (T == true)) ? "true" : "false";
streaming the boolean value of T == true, then evaluating (but ignoring) the expression "true". Most compilers will give a warning, if you enable a sensible set of warnings.
Here is a reference to the operator precedences, showing << with a higher precedence (7) than ?: (15): http://en.cppreference.com/w/cpp/language/operator_precedence
The conditional operator ? : does have precedence - it's number 15 in this table, lower than << and >> operators, which are number seven.
The rule that I follow to avoid mistakes like that is to use parentheses when in doubt. The rationale is simple: if you need to look up the priority in a table, good chances are that the readers of your code, including yourself, would need to do the same thing at some later time.
A lot of the other questions answer why you are seeing that behavior but they don't answer why the ternary operator has low priority.
The decision was made to have low ternary priority because we don't want the code
a<d ? 10 : 100
to end up meaning
a < (d ? 10 : 100) //BAD: not what we normally expect
we want it to mean
(a<d) ? 10 : 100
Low priority for the ternary operator achieves this goal. This sort of thing is the whole reason for operator precedence that you find in languages. The goal is to make it convenient to write expressions that are expected to be normal in the language. Right? If not, it could just be left to right with parentheses. Which would be annoying to use and you'd quickly propose some sort of convenient operator precedence.
It is true that the ?: operator has no clearly defined priority. But the example in question does not really illustrate that. The relative priorities of << and ?: are rather unambiguous. All your example shows is that the priority of << is higher than the priority of ?:.
As for the more general issue of the priority of ?: operator... ?: operator has relatively convoluted format, compared to other operators: it has three non-uniform operands. Because of that non-uniformity the part before ? has different syntactic grouping properties than the parts after ?.
After all, "priorities" are a derivative trick invented to simplify visualization and memorization of syntactic groupings defined by the grammar. Not all C++ operators conform to that trick though. The ?: operator happens to be the one that does not, which is why a properly written priority table will typically have a side note for ?: operator, explaining its unusual properties. Again, the part before the ? has different priority than the parts after the ?, which is why it is impossible to properly place the ?: operator into a linear table of priorities.
Unless I'm forgetting something, the ?: operator is the only operator without a straightforwardly definable priority.
P.S. Things with ?: operator were even worse in C. C++-related changes to the grammar made ?: to conform better to the idea of linear priority.
Like the other answers note, the << operator has higher precedence than the ? operator. Here is my opinion on why it is so.
Using bit-shift (<<) with the choice operator makes sense; for example
(T == true) ? (whatever << 1) : (whatever << 2)
(T == true) ? whatever << 1 : whatever << 2 // same as above
When the designers of C++ invented operator overloading, they decided to reuse the bit-shift operator << as a streaming operator. Had they introduced another, completely new streaming operator (e.g. <<<), it would get very low precedence, so the code would work as expected:
cout <<< (T == true) ? "true" : "false";
However, introducing a new operator just for it to be overloaded would undermine the idea of usefulness of operator overloading, which was a fascinating idea back then. So they decided to use an old (existing) operator.
The ternary conditional operator does have a precedence, except that it's at the bottom of the list (value 15). Only throw and , (comma) have a lesser precedence. See this reference for C++ Operator Precedence.
because of brackets, firstly statement (T == true) is evaluated, then comes the left shift operator and 1 which was evaluated earlier is sent to cout. later, the ternary operator evaluates "true" but it is ignored.
all in all, ternary operator has precedence, but one of the lowest.
In C++, you can double up the indirection operator:
vector<unique_ptr<string>> arr{make_unique<string>("Test")};
cout << **arr.begin() << endl;
But you can't double up the dereference operator:
cout << arr.begin()->->c_str() << endl;
Instead, you have to settle with this (IMO) less-legible alternative:
cout << (*arr.begin())->c_str() << endl;
operator-> is a unary operator that returns a pointer type, so it seems natural to be able to chain them. Is there any good reason for this limitation? Is there some parsing difficulty I'm not seeing?
Edit
In 5.2.5/3, The C++ standard specifies:
If E1 has the type “pointer to class X,” then the expression E1->E2 is
converted to the equivalent form (*(E1)).E2
I just wish it was specified as:
If E1 has the type “pointer to class X,” then the expression E1-> is
converted to the equivalent form (*(E1)).
It actually seems contrary for this definition to include E1 and E2, since an overloaded operator-> isn't a binary operator.
Here is a not too technical explanation.
-> is shorthand for the * and the . in (*someptr).memberfunc(). Therefore this can be expressed as someptr->memberfunc().
Two -> would be, in your example, the same as (*(*arr.begin()).).c_str(). Notice the extra dot. This doesn't make sense and it doesn't compile, since . is a binary operator, and * is a unary operator. Therefore, you would have an "extra" dot. You really want two *'s and only one .. Use one -> and one * as you have done.
-> means "dereference and get a member." You want to dereference twice, and get a member once, so double -> is not what you want.
Note that:
(*a).b
a->b
are the same thing
so
a->->b
(*a)->b
(*(*a)).b
So would be okay as an operator, but that isn't in the spirit of -> the spirit is to access things that are pointed to in structures. I'd rather type a->b than (*a).b
So while no technical reason (*a)->b tells you "a is a pointer to a pointer of a structure with b" and a->b->c is totally different to a->->b even though they look similar.
If I understand this correctly, You can get the behaviour that you are looking for with a better design.
The dereference operator actually doesn't really works just as an operator that retrieves a values for you from a pointer, if offers a slightly more complex behaviour.
The business logic of the -> operator is clearly illustrated here, it is also being expanded here, here and you can find a birds eye view about pointer related operators here .
As you can easily guess, If you have T->t you can use the drill down behaviour at your advantage, assuming that you have properly designed and defined T and its own -> operator.
This is a solution that can easily bring some polymorphic behaviour to your application.
Probably like many, I typed this typo
int a = 0;
cout << a < " "; //note the '<'
However, the MSVC++ compiler threw just a warning
warning C4552: '<' : operator has no effect; expected operator with
side-effect
though I expected a compilation error. Is it indeed standard complaint code? Does any implicit type conversion or overloading happen which make the code valid? I am also confused whether < operator is comparing the string " " with an integer a or with the result of cout << a
A related SO post is here.
The << operator has a higher precedence than <, so this is parsed as
(cout << a) < " ";
You are not really comparing a string with an integer. Instead, you are comparing the return value of ostream::operator<<, which is std::cout itself, to the string literal. This isn't legal (in the sense that is has an unspecified result, and it is not meaningful) either, clang warns:
warning: result of comparison against a string literal is unspecified
The reason why it compiles is that up until C++11, std::ostream can be implicitly converted to void *. Also, the string literal of type const char[2] decays into a pointer of type const char *. So, the < operator now takes two pointers, which is permitted, although its result is not specified, because the two pointers don't point to the same object.
Actually, since it is (cout << a) < " ", we're comparing an ostream with " ". The ostream class has an operator to convert it to void *. You can compare a void * with a const char * without cast, so the compiler is happily doing that, then realizing that you are not using the result of the comparison, and issues the warning.
One of those quirky things in C++.
It is down to operator precedence
i.e.
The line equates to (cout << a) < " "; - Hence the <" " does nothing!
EDIT
This bit returns an object (cout << a) returns an object of type ostream where it does not have an overloaded operator <, so either the compiler gives up (C++11) or scratches its head amd has a bash at the integer operator (i.e. pointers etc).