Why can I overload and use ++ operator in LHS and RHS while + one works just in LHS mode?
class B {
public:
string operator ++ () { return "hello"; }
string operator + () { return "hello2"; }
};
int main ()
{
B b;
string s = +b ;
s = b+ ; // compile error syntax error : ';'
s = b++;
s = ++b;
return 0;
}
Overloaded operators can only be used with the same syntax as the corresponding built-in ones. The built-in ++ is defined as either a prefix or postfix operator; the built-in + is only defined as a prefix operator (and of course as a binary operator).
Note that your code won't compile even without the b+ line, since you're missing a postfix version of ++:
string operator ++ (int) { return "postfix"; }
Why I can overload and use ++ operator in LHS and RHS
Your code actually produces two errors:
main.cpp:16:12: error: expected expression
s = b+ ; // compile error syntax error : ';'
^
main.cpp:18:10: error: cannot increment value of type 'B'
s = b++;
~^
So you actually haven't overloaded the post-increment operator, only the pre-increment operator. Your question remains, however, since you could overload post-increment if you wanted to but C++ does not offer any similar syntax for overloading a postfix unary plus operator.
C++ does not change the way operators in expressions are parsed based on operator overloads. It will only allow you to overload operators that already exist, and those operators will be parsed exactly as if operator overloads do not exist. It's only after parsing that C++ will then look around for operator overloads to figure out what the parsed expression means. Thus C++ offers a way to overload a post-increment operator because it already handles parsing the post-increment operator, but it does not already handle parsing a postfix plus operator.
Limiting C++ operator overloads to existing operators was done because it is simpler to implement a parser if the parser doesn't have watch out for arbitrary uses of operators. That doesn't mean it can't be done, however. The language Swift, for example, allows arbitrary operator overloading for binary, prefix unary, and postfix unary operators, including creating completely new operators.
Related
We know ++ and - - can be prefix or postfix and it depends on the position of the operand. for example :
++a prefix because the operand is on the right of the operator.
a++ postfix because the operand is on the left of the operator.
But In complicated expressions things become confusing. for example :
! - -a == ++ ! b I know to solve this i must apply the precedence rule but that depend on how i will consider the type of ++ , a postfix or prefix.
My question how can i decide if an operator a postfix or a prefix and more generaly how can i determine the operand of an unary operator ?
Don't.
Making some assumptions about type, your code should be:
!(-(-a)) == ++(!b)
Note the use of parentheses to obviate the need to even think about precedence.
Except this isn't a valid expression, because you can't increment an rvalue/temporary (assuming you aren't overloading operator! and returning a reference, which would be non-idiomatic and weird).
Also each side of the == should be split off into a variable declaration for clarity.
const bool isItHot = !a;
const bool isItCold = !b; // ignoring your ++ for now
return (isItHot == isItCold);
If you really need a tool to work out the precedence for you, Geordi can do it, or you can work it out from some documentation.
is subscript operator [ ] unary or binary operator ?
I'm quite new to C++ and was going through operator operloading and wondered
is subscript a unary or binary?
The subscript operator is a binary operator in the strict sense as it takes two arguments, the reference to the object and the value.
int arr[3];
Here you can see that [] operator makes use of both arr and 3.
According to the C++ Standard
13.5.1 Unary operators
1 A prefix unary operator shall be implemented by a non-static member
function (9.3) with no parameters...
and
13.5.2 Binary operators
1 A binary operator shall be implemented either by a non-static member
function (9.3) with one parameter...
Thus the subscript operator is a binary operator.
The Unary operators in C++ are:
unary-operator: one of
* & + - ! ~
and also you may add to unary operators
++ cast-expression
-- cast-expression
I wrote this program:
#include <iostream>
using namespace std;
void unequalityOperator(){
cout << "Running unequalityOperator..." << endl;
bool a = true, b = false;
if ( a != b ) cout << "!=" << endl;
if ( a =! b ) cout << "=!" << endl;
}
int main()
{
unequalityOperator();
system("pause");
return 0;
}
And I was surprised that it run and printed both of the strings. So I tried the same thing with some other binary operators like <=, >=, etc. but it didn't work.
Therefore I would like to understand whether there is a difference between != and =!.
I do know that there are some operators like +=, -=, etc. that work differently and, e.g., the difference between += and =+ is that the addition will occur before or after (respectively) the actual command. And for this reason I suspect that there is difference with the hierarchy in the implementation of these operators, but I am not really sure what.
So please help me understand.
The expression a = !b is an assignment of the value !b into the variable a.
The evaluation of this expression within an if statement is the new value of a.
Since b is set to false and you are assigning !b into a, this value is true.
In first case the != operator is a single inequality operator. In second case it is an assignment operator = with logical not operator !. So in the second case you are assigning not b to a and returning it's result true
This might help to clear things up:
!= : not-equal operator
=! : these are really two operators: assignment operator and unary logical NOT operator
+= : sum-assignment operator
=+ : these are really two operators: assignment operator and unary + operator
-= : difference-assignment operator
=- : these are really two operators: assignment operator and unary - operator
Also, as these were in your question before being edited out:
++= : two operators: postfix increment operator and assignment operator
=++ : two operators: assignment operator and prefix increment operator
I hope you notice the pattern.
For reference:
http://en.cppreference.com/w/cpp/language/operator_precedence
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
While reading this article it seems that the operator + is unary. How is that.
From my understanding a unary operator is an operator that does not depend on another variable for its operation like ++a or a-- . How is the variable '+' unary. I thought it was binary ? I would appreciate it if some one could clear this up.
+ is both a unary and binary operator. The unary + form (+a) forces the operand to be evaluated as a number or a pointer, while the binary form + form (a + b) is addition.
Unary + is generally the opposite of unary -; applying it to any numeric value will not change it. (+1 == 1) However, it does have some uses, including forcing an array to decay into a pointer:
template <typename T> void foo(const T &) { }
void test() {
int a[10];
foo(a); // Calls foo<int[10]>()
foo(+a); // Calls foo<int*>()
}
(Demo)
It's the same deal with the - and * operators. You have -a (negation) and a - b (subtraction); *a (pointer dereference) and a * b (multiplication).
You overload both versions differently. For overloading via member functions:
public:
T operator+() const; // Unary
T operator+(const U &) const; // Binary
As with any other operator overload, both forms can return a value different from their enclosing type; for example you might have a string class whose operator+() returns a numeric type. This would be in line with the convention of unary + evaluating its operand as a number.
You can overload these operators as free functions, too:
T operator+(const U &); // Unary, called on type U and returns T.
T operator+(const U &, const V &); // Binary, called on types U and V and returns T.
Unary + as in +a is defined to complement unary - (-a). It is the "default" so actually not often if ever used. However it can be used with variables refering to classes, where it can be overloaded to have a class-specific meaning. So it is not quite entirely useless.
While trying to learning operator overloading, I read the following statements from C++ Primer. Frankly speaking, I do not quite understand what does the message that these statements want to deliver. The examples include defining both member binary operator and nonmember binary operator. Is there any difference when using them?
Ordinarily we define the arithmetic and relational operators as nonmember functions and we define assignment operators as members:
Sales_item& Sales_item:: operator (const Sales_item&)
Sales_item operator_(const Sales_item&, const Sales_item&);
Both addition and compound assignment are binary operators, yet these functions define a different number of parameters. The reason for the discrepancy is the this pointer.
Yes, there is a difference in actual use. In particular, when you overload an operator as a non-member function, conversions can be applied to either operand (or both operands). When you overload a binary operator with a member function, conversions can only be applied to the right operand.
This can lead to some oddities. For example, consider writing a "bignum" package and you wanted to overload operator+ to handle bignums. If you overload it as a member function, you get an oddity like this:
int x = 2;
bignum y = 3;
bignum z;
z = y + x; // works fine.
z = x + y; // doesn't work: x isn't a bignum, and can/won't be converted to one
If, instead, you overload operator+ using a non-member function, both of the operations will work (presuming you have a constructor to create a bignum from an int, which you'd almost certainly want).
A few operators (particularly assignment operators, such as =, +=, -=, etc.) are special. A conversion creates a temporary object, and assigning to a temporary object 1) isn't allowed, and 2) wouldn't make sense or accomplish much anyway. Therefore, when you're overloading assignment operators, you always use a member function.