This question already has answers here:
What is the "-->" operator in C++?
(29 answers)
Closed 4 years ago.
I have encountered <<++ and >>++ operators many time in`C++, but I don't understand what they are. What is the specific meaning and use of these operators, and how are they different from right shift and left shift operator?
C++ compilers ignore whitespace unless in certain situations such as string literals.
<<++ and >>++ is really just a bit-shift operatior << or >>, followed by an increment operator ++.
Consider this code:
a <<++ b is equivalent to
a<<++b because the spaces are ignored in this context, and then equivalent to
a << ++b (a left shifted by a pre-incremented b)
a << (++b) due to operator precedence. Bit shift operators have lower precedence than incrementation.
There are two separate operators in both cases: left shift (<<), right shift (>>) and increment operator (++).
You can rewrite the following:
a >>++ b
as:
a >> (++b)
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
cout << string_1 << string_2 << string_3;
The line above is processed from left to right, first the operator "<<" operates on "cout" and "string_1", which returns an ostream object which is later used to operate on "string_2", and so on to "string_3".
a = b = 5;
In the line above, the code is processed from right to left. First the operator "=" operates on "b" and "5", which returns an int object to operate with "a" on the next "=" operator.
I might be wrong on how these lines are processed.
Please help me understand why the compiler is changing the order of operations in both cases.
This is a wise design decision.
Because you intuitively expect
cout<< string_1 << string_2 << string_3;
to emit the three strings in that order, and you expect
a = b = 5;
to assign 5 to both a and b (rather than performing a= b; b= 5;)
The fundamental reason behind this difference in processing order is operator precedence1.
Precedence and associativity determine how the operands are grouped in an expression.
So there are 2 important points to keep in mind here:
Operands of operators with higher precedence group more tightly than
operands of operators at lower precedence.
Associativity determines how to group operands with the same precedence.
Lets consider some examples to clear this up.
Example 1
Consider the expression 3+4*5+2.
Now the value(result) of this expression depends upon how the subexpressions are grouped.
In this example, multiplication and division have the same precedence as each other but they have higher precedence than addition. Thus, using Point 1 above, operands to muliplication and division group before operands to addition.
Also, the arithmetic operators are left associative which means operands of operators at the same precedence group left to right. This is what associativity meant in point 2 above.
Now, using these two facts the expression 3+4*5+2 is equivalent to:
((3+(4*5))+2)
which will result in a value of 25.
Example 2
Consider the expression cin >> x >> y;
In this example, the IO operators are left associative which means they group left to right. This is why we are able to combine IO operations in a single expression as above. This also means that the above expression is equivalent to writing:
((std::cin >> x) >> y);
Example 3
Lets come back to your example expression cout << string_1 << string_2 << string_3
As i said in example 2, IO operators are left associative which means they group left to right. Again, this means the above expression is equivalent to writing:
(((cout << string_1) << string_2) << string_3)
Example 4
Consider the expression a = b = 5
In this case, the assignment operator is right associative which means they group right to left. Thus the above expression is equivalent to writing:
(a = (b = 5))
This means 2 things:
the rightmost assignment b = 5 is the operand of the leftmost assignment operator.
because assignment returns its left-hand operand, the result of the rightmost assignment(which will be b in this case) is assigned to a.
1 Precedence specifies how the operands are grouped. It says nothing about the order
in which the operands are evaluated. There is no concept of left-to-right or right-to-left evaluation in C++.
As #UnholySheep posted in a comment:
Because that's how the operator associativity is defined: https://en.cppreference.com/w/cpp/language/operator_precedence
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Operator overloading
I was wonder how can I over load the Conditional operator in cpp?
int a,b,c;
a=10;
b=11;
c = (a>b) ? a : b;
Is it possible?
You cannot overload the conditional operator.
Several operators cannot be overloaded. These operators take a name, rather than an object, as their right operand:
Direct member access (.)
Deference pointer to class member (.*)
Scope resolution (::)
Size of (sizeof)
The conditional operator (?:) also cannot be overloaded.
Additionally, the new typecast operators: static_cast<>, dynamic_cast<>, reinterpret_cast<>, and const_cast<>, and the # and ## preprocessor tokens cannot be overloaded.
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=23
No, you can't overload the conditional operator, since it's simply shorthand for a simple if..else block.
You can however overload the operators used in the condition, but not for primitive types such as int, like you have in your example above.
This question already has answers here:
What does the operation c=a+++b mean?
(9 answers)
Why doesn't a+++++b work?
(9 answers)
Closed 9 years ago.
Given the following code:
int a=0,b=1;
int r=a+++b;
which are the operations performed and in which order?
a++ + b
a + ++b
I this compiler specific or does it depend on the standard?
It is (a++) + b but not because of operator precedence.
It is parsed as (a++) + b because the compiler takes the longest token it can from a sequence of characters. In other words, the lexer keeps reading characters until it encounters something that can't be part of the same token as what it already has.
This is also how it interprets >= as one token instead of > and =, and double as 'double' not 'do uble'.
There are rules of operator precedence for statements like
a || b && c
// "a || (b && c)" NOT "(a || b) && c", because && takes precedence
However, in your case the operators ++ and + have already been determined. Once the operators have been determined, the rules of operator precedence can apply.
There are some good answers to Why doesn't a+++++b work in C? that should explain this in more detail.
That is governed by the operator precedence. Since postfix ++ has a higher precedence than the + operator it binds tighter to a is post incremented then added to b so the result is:
(a++) + b
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);
I know this is silly question but I don't know which step I'm missing to count so can't understand why the output is that of this code.
int i=2;
int c;
c = 2 * - ++ i << 1;
cout<< c;
I have trouble to understanding this line in this code:
c = 2 * - ++ i <<1;
I'm getting result -12. But I'm unable to get it how is precedence of operator is working here?
Have a look at the C++ Operator Precedence table.
The ++i is being evaluated, yielding 3.
The unary - is being evaluated, yielding -3.
The multiplication is being done1, yielding -6.
The bit shift is evaluated (shifting left by 1 is effectively multiplying by two) yielding -12.
The result -12 is being assigned to the variable c.
If you used parentheses to see what operator precedence was doing, you'd get
c = ((2 * (-(++i))) << 1);
Plus that expression is a bit misleading due to the weird spacing between operators. It would be better to write it c = 2 * -++i << 1;
1 Note that this is not the unary *, which dereferences a pointer. This is the multiplication operator, which is a binary operator.
Operator precedence defined the grouping between the operators and their operands. In your example the grouping is as follows
c = ((2 * (-(++i))) << 1);
That's how "precedence of operator is working here" and that's the only thing it does.
The result of this expression is -6 shifted one bit to the left. This happens to be -12 on your platform.
According to your comment in another answer, you mistakenly believe that operator precedence somehow controls what is executed "first" and what is executed "next". This is totally incorrect. Operator precedence has absolutely nothing to do with the order of execution. The only thing operator precedence does, once again, is define the grouping between the operators and their operands. No more, no less.
The order of execution is a totally different thing entirely independent from operator precedence. In fact, C++ language does not define any "order of execution" for expressions containing no sequence points inside (the above one included).