If I manually overload the == operator for a structure, do I get the != operator for free (presumably defined to be the boolean opposite), or do I have to overload it manually (even if to just return !(this == rhs)?
Edit-The question is not whether or not I CAN overload both operators, but whether I must overload inequality if I've already overloaded the equality operator. Regardless, good answers have been given.
Overloading operator == does not give you operator !=. You have to do it manually and the canonical way is to implement it in terms of operator == as in !(left == right).
The semantics of the operators are not dictated by the standard. You could very well overload operator == to mean equality yet overload operator != to something different like addition or even equality again (not that this is a good practice, in fact it should be discouraged. When in doubt, do as the ints do...).[Refer (1) Below]
On a side note, Boost.Operators can help you provide canonical implementations for operators. There is also std::rel_ops with a canonical implementation for operator !=.
(1) To know more about it read Three basic rules of operator overloading in C++.
No nothing is for free. You pay for what you use in C++(in case of Operator Overloading).
You only get the Operator which you overload nothing more.
Also, It is a good practice that if you overload == operator then you should overload != as well because the users of your class will expect that to be available.
Operator Overloading C++ FAQ should be a good read.
Answering the updated Question:
The question is not whether or not I CAN overload both operators, but whether I must overload inequality if I've already overloaded the equality operator.
NO.
There is no such requirement that you Must overload != If you need to overload ==. However,it is a good practice that you Should overload operators related to each other.
Why is it a good practice?
Think it from the perspective of the user of your class. If the user of your class can use ==(equality criteria) to compare objects of your class, naturally they are going to expect that they should be able to use !=(Non-equality criteria) as well, this stems from the fact that these two operators are related closely and supported for all built-in tyes.
What happens if you disregard the should and not overload != when you overload ==?
If the users of your class use != they will get a compile error.
They would frown a bit about not being provided with != when they are provided with == and they will have to realign their logic to use == instead of the !=.
So you can live with it but be ready to expect a few frowns and complaints of inconvinience and not providing user friendly interface.
You have to overload each operator. != and == are not linked.
It doesn't, and thankfully it is the way it is. For example, you might want a structure, where both a!=b and a==a are true. They are not necessary the inverse, they can be anything you want.
Boosts the creativity. :)
For example if you don't know the result of a comparison, or it is generally not known, then it would be reasonable to a==b and a!=b return the same.
Example: http://en.wikipedia.org/wiki/Three-valued_logic
Related
If I manually overload the == operator for a structure, do I get the != operator for free (presumably defined to be the boolean opposite), or do I have to overload it manually (even if to just return !(this == rhs)?
Edit-The question is not whether or not I CAN overload both operators, but whether I must overload inequality if I've already overloaded the equality operator. Regardless, good answers have been given.
Overloading operator == does not give you operator !=. You have to do it manually and the canonical way is to implement it in terms of operator == as in !(left == right).
The semantics of the operators are not dictated by the standard. You could very well overload operator == to mean equality yet overload operator != to something different like addition or even equality again (not that this is a good practice, in fact it should be discouraged. When in doubt, do as the ints do...).[Refer (1) Below]
On a side note, Boost.Operators can help you provide canonical implementations for operators. There is also std::rel_ops with a canonical implementation for operator !=.
(1) To know more about it read Three basic rules of operator overloading in C++.
No nothing is for free. You pay for what you use in C++(in case of Operator Overloading).
You only get the Operator which you overload nothing more.
Also, It is a good practice that if you overload == operator then you should overload != as well because the users of your class will expect that to be available.
Operator Overloading C++ FAQ should be a good read.
Answering the updated Question:
The question is not whether or not I CAN overload both operators, but whether I must overload inequality if I've already overloaded the equality operator.
NO.
There is no such requirement that you Must overload != If you need to overload ==. However,it is a good practice that you Should overload operators related to each other.
Why is it a good practice?
Think it from the perspective of the user of your class. If the user of your class can use ==(equality criteria) to compare objects of your class, naturally they are going to expect that they should be able to use !=(Non-equality criteria) as well, this stems from the fact that these two operators are related closely and supported for all built-in tyes.
What happens if you disregard the should and not overload != when you overload ==?
If the users of your class use != they will get a compile error.
They would frown a bit about not being provided with != when they are provided with == and they will have to realign their logic to use == instead of the !=.
So you can live with it but be ready to expect a few frowns and complaints of inconvinience and not providing user friendly interface.
You have to overload each operator. != and == are not linked.
It doesn't, and thankfully it is the way it is. For example, you might want a structure, where both a!=b and a==a are true. They are not necessary the inverse, they can be anything you want.
Boosts the creativity. :)
For example if you don't know the result of a comparison, or it is generally not known, then it would be reasonable to a==b and a!=b return the same.
Example: http://en.wikipedia.org/wiki/Three-valued_logic
Why is it not possible to overload the ternary operator ' ?: '?
I use the ternary operator often to consolidate if statements, and am curious why the language designers chose to forbid this operator from being overloaded. I looked for an explanation as to why in C++ Operator Overloading but did not find one describing why this isn't possible. The only information the footnote provides is that it cannot be overloaded.
My initial guess is that overloading the operator will almost always violate number one or two of the principles given in the link above. The meaning of the overload will rarely be obvious or clear or it will deviate from its original known semantics.
So my question is more of why is this not possible rather than how, as I know it cannot be done.
if you could override the ternary operator, you would have to write something like this:
xxx operator ?: ( bool condition, xxx trueVal, xxx falseVal );
To call your override, the compiler would have to calculate the value of both trueVal and falseVal. That's not how the built-in ternary operator works - it only calculates one of those values, which is why you can write things like:
return p == NULL ? 23 : p->value;
without worrying about indirecting through a NULL pointer.
I think the main reason at the time that it didn't seem worth
the effort of inventing a new syntax just for that operator.
There is no token ?:, so you'd have to create a number of
special grammar rules just for it. (The current grammar rule
has operator followed by an operator, which is a single
token.)
As we've learned (from experience) to use operator overloading
more reasonably, it has become apparent that we really shouldn't
have allowed overloading of && and || either, for the
reasons other responses have pointed out, and probably not
operator comma as well (since the overloaded versions won't have
the sequence point which the user expects). So the motivation
to support it is even less than it was originally.
One of the principles of the ternary operator is that the true / false expression are only evaluated based on the truth or falseness of the conditional expression.
cond ? expr1 : expr2
In this example expr1 is only evaluated if cond is true while expr2 is only evaluated if cond is false. Keeping that in mind lets look at what a signature for ternary overloading would look like (using fixed types here instead of a template for simplicity)
Result operator?(const Result& left, const Result& right) {
...
}
This signature simply isn't legal because it violates the exact semantics I described. In order to call this method the language would have to evaluate both expr1 and expr2 hence they are no longer conditionally evaluated. In order to support ternary the operator would either need to
Take a lambda for each value so it could produce them on demand. This would necessarily complicate the calling code though because it would have to take into account lambda call semantics where no lambda was logically present
The ternary operator would need to return a value to denote whether the compiler should use expr1 or expr2
EDIT
Some may argue that the lack of short circuiting in this scenario is fine. The reason being that C++ already allows you to violate short circuiting in operator overloads with || and &&
Result operator&&(const Result& left, const Result& right) {
...
}
Though I still find this behavior baffling even for C++.
The short and accurate answer is simply "because that's what Bjarne decided."
Although the arguments about which operands should be evaluated and in what sequence give a technically accurate description of what happens, they do little (nothing, really) to explain why this particular operator can't be overloaded.
In particular, the same basic arguments would apply equally well to other operators such as operator && and operator||. In the built-in version of each of these operators, the left operand is evaluated, then if and only if that produces 1 for && or a 0 for ||, the right operand is evaluated. Likewise, the (built in) comma operator evaluates its left operand, then its right operand.
In an overloaded version of any of these operators, both operands are always evaluated (in an unspecified sequence). As such, they're essentially identical to an overloaded ternary operator in this respect. They all lose the same guarantees about what operands are evaluated and in what order.
As to why Bjarne made that decision: I can see a few possibilities. One is that although it's technically an operator, the ternary operator is devoted primarily to flow control, so overloading it would be more like overloading if or while than it is like overloading most other operators.
Another possibility would be that it would be syntactically ugly, requiring the parser to deal with something like operator?:, which requires defining ?: as a token, etc. -- all requiring fairly serious changes to the C grammar. At least in my view, this argument seems pretty weak, as C++ already requires a much more complex parser than C does, and this change would really be much smaller than many other changes that have been made.
Perhaps the strongest argument of all is simply that it didn't seem like it would accomplish much. Since it is devoted primarily to flow control, changing what it does for some types of operands is unlikely to accomplish anything very useful.
For the same reason why you really should not (although you can) overload && or || operators - doing so would disable short-circuiting on those operators (evaluating only the necessary part and not everything), which can lead to severe complications.
Previous answers focused on short-circuiting, which is somewhat valid but not even the real problem with trying to do this IMO.
The closest possible implementation of the existing ternary operator (without short circuiting) would have to look like this:
template<typename T0, typename T1>
std::variant<T0, T1>&& operator?:(bool predicate, T0&& arg0, T1&& arg1)
{
if(predicate)
return { std::forward<T0&&>(arg0) };
return { std::forward<T1&&>(arg1); }
}
However, T0 might be void. T1 might be void. This won't build in either of those cases.
The variant is necessary because T0 and T1 might not be implicitly convertible to one another and the return type can't be used for function overload resolution, and that was a C++17 library addition. But it still doesn't really work, because variant isn't implicitly convertible to any of its possible types.
Is it a bad idea to overload &&, || or comma operator and Why?
I wouldn't overload operator&& or operator||. Even if you define a class that gives rise to a Boolean algebra (finite sets, for example), it would probably be a better choice to overload operator& and operator|.
The reason is that C++ programmers expect special semantics for operator&& and operator||: they are short-circuited, i.e. don't evaluate their right-hand argument if not necessary. You can't get this behavior by overloading, since you'll be defining a function.
Overloading operator, has been done in e.g. the Boost.Assign library. This is also the only example of its overloading that I know, and I've never even considered overloading it myself. You'd better have a very specific use case for it where no other operator is suited.
For overloading the logical operators in C++, the operands must be evaluated, which isn't the way things normally work with short circuiting of built-in types.
Look at the below link.
Don't overload logical operators in C++
You shouldn't overload any operators in a way that is surprising. :-)
If you can do it in a way that makes sense (not only to you), it is fine to do so.
Like others have said, the logical operators are special in that they have the effect of lazy evaluation. So your overloads should probably preserve this lazy effect, like with expression templates, or only be used where people don't expect this effect anyway.
It is usually a bad idea: those three operators have a sequencing effect which is lost when you overload them. Loosing that sequencing effect can cause arm (i.e. strange bugs) to those not expecting that lost.
There are cases with template expressions where you can keep the sequencing effect, in those cases I see no problem in overloading them.
The overloads of operator, I know of have another problem: they work in such a way that the apparent chains of operation isn't the real one. Usually, they are used in context when it makes no difference, but once in a blue moon, that is another source of a strange bugs.
I'd say it depends on what your overloads are doing. For example, && and || are expected to work as logical conditions, so if your overload semantics work somehow differently, they can confuse other people (or even yourself, if you don't use them for a while and forget what they do). Consider what you would expect the operators to do if you wouldn't know how they are overloaded and if it would be clearer to just use normal methods instead.
As the others have said, missing lazy evaluation is the main reason to avoid overloading logical operators.
However, there is one very good reason to overload them: Expression templates. The Boost.Lambda library does this, and it's very useful!
Its bad idea except situations when your classes represents some logic entity, because overloaded operators will disorientate and can cause new bugs in code.
It is reasonable that sizeof and typeid cannot be overloaded, but I can't see the harm in overloading ?:, .* and .. Are there technical reasons for this?
To quote Bjarne Stroustrup:
There is no fundamental reason to
disallow overloading of ?:. I just
didn't see the need to introduce the
special case of overloading a ternary
operator. Note that a function
overloading expr1?expr2:expr3 would
not be able to guarantee that only one
of expr2 and expr3 was executed.
...
Operator . (dot) could in principle be
overloaded using the same technique as
used for ->. However, doing so can
lead to questions about whether an
operation is meant for the object
overloading . or an object referred to
by . ... This problem can be solved in
several ways. At the time of
standardization, it was not obvious
which way would be best.
Source
If you overload ., how would you access class members? What would be the meaning of obj.data?
What would the syntax be?
In fact, there are good reasons for not overloading any operator
which doesn't evaluate all of its operands: you shouldn't
overload && or || either (except in special cases). You can't
simulate this with an overloaded operator. Consider something
like:
p != NULL ? defaultValue : p->getValue()
where the type of defaultValue or p->getValue() causes overload
resolution to pick up your overload. It's a common idiom, but
it can't be made to work if you overloaded ?:.
Here's some reading material C++ FAQ Lite :)
In general there would be no benefit to overloading the operators above. What additional semantics would you be trying to implement?
The reason for overloading operators is to provide intuitive syntax to the user of your class. For example, it makes sense to overload + and += for strings. It's obvious to another developer what that means.
It's really not obvious what you would overload ?: for ... That said there are no technical reasons I am aware of that prevented these operators from being overloaded.
Overloading the -> operator allows for reference counted pointers to be created such as boost::shared_ptr. The concept of 'negating' an object might have different meanings in different contexts, so it's reasonable to occasionally overload this operator.
Defining "operator bool" is enough for ?: to work.
For operator . think of this: SomeClass."SomeString!!"
These overloadings prohibit compiler's lexer from parsing the file correctly.
The reason you can overload most operators is to be able to simulate built in types. Since none of the built in types can use the . operator, it wouldn't serve any purpose. operator* and operator-> are there so you can make your own pointer classes. All the math and boolean operators are there to be able to make your own numeric classes.
When overloading operators, is it necessary to overload >= <= and !=?
It seems like it would be smart for c++ to call !operator= for !=, !> for operator<= and !< for operator>=.
Is that the case, or is it necessary to overload every function?
Boost operators might be what you are looking for. These will derive most of your operators based on a few fundamental ones.
That C++ does not provide this automatically makes sense, as one could give totally different meanings to < and >, for example (although it would often be a bad idea).
I am going to take a minority viewpoint here. If you already use boost then using boost operators is not that big of a deal. It may be the correct and tested way to do things but adding boost dependency just for the operators is an overkill.
It is possible to write complex C++ programs without boost (which I personally find aesthetically unpleasant) and so to Keep It Simple (Stupid), to answer OP's question, if you overload operator ==, you should also overload operator !=. Same is true for <, >, ++ etc.
Yes, it is necessary, if you want all of them to work the way you want them to work.
C++ does not force any specific semantics on most of the overloadable operators. The only thing that is fixed is the general syntax for the operator (including being unary or binary and things like precedence and associativity). This immediately means that the actual functionality that you implement in your overload can be absolutely arbitrary. In general case there might not be any meaningful connection between what operator == does and what operator != does. Operator == might write data to a file, while operator != might sort an array.
While overloading operators in such an arbitrary fashion is certainly not a good programming practice, the C++ language cannot assume anything. So, no, it cannot and will not automatically use ! == combination in place of !=, or ! > combination in place of <=.
No, you only need to overload operator == and operator <, the standard library will take care of the rest :)
(EDIT: see using namespace std::rel_ops ;)
Yes it is necessary to overload whichever operators you want to be used as you define them - C++ will not make the decision you describe above; however, keep in mind that if the reason you are overloading is to sort your class, than you only need to override the operators used by the sort routine. In the case of the RTL sort algorithm you only need to override < and =.
Yes! They are each technically different operators. C++ compilers are not inherently inference engines, they are parsers/compilers. They will only do as much as you say to do.
http://www.parashift.com/c++-faq-lite/operator-overloading.html, http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
There are a few shortcuts you can use, such as CRTP to get them automatically injected (see the various Compare classes) into your class.
C++ does not, as a language, define any operator in terms of any other overloaded operator. Just because you have operator+, doesn't mean you get operator+= for free (unlike Ruby and Scala). Just because you have operator < and == doesn't mean you get <= for free. Just because you have operator == doesn't mean you get != for free (unlike Ruby and Scala). Just because you have unary operator * (unary) doesn't mean you get operator -> for free.
std::relops (if imported correctly) and provide default definitions, and Boost provides some mix-ins that define all of the comparison operators in terms of < and ==.
You can use overloading to use user defined names.
Operator overloading means using the same operator to do perform operation on different items which are not in that category. Function overloading means using the same name of function but different arguments, so as to overcome the overhead when the same function is called during looping.