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.
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
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
I've started learning C++, so I don't know in my lack of knowledge/experience why something so seemingly simple to a rookie as what I'm about to describe isn't already in the STL. To add a vector to another vector you have to type this:
v1.insert(v1.end(), v2.begin(), v2.end());
I'm wondering whether in the real world people just overload the += operator to make this less verbose, for example to the effect of
template <typename T>
void operator+=(std::vector<T> &v1, const std::vector<T> &v2) {
v1.insert(v1.end(), v2.begin(), v2.end());
}
so then you can
v1 += v2;
I also have this set up for push_back to "+=" a single element to the end. Is there some reason these things should not be done or are specifically avoided by people who are proficient in C++?
This is actually a case where I would like to see this functionality in the form of an overload of append(). operator+= is kinda ambiguous, do you mean to add the elements of each vector to each other? Or you mean to append?
However, like I said, I would have welcomed: v1.append(v2); It is clear and simple, I don't know why it isn't there.
I think the main reason is that the semantics of += aren't obvious. There's the meaning that you have here, but there's also an equally valid meaning, which is element-wise addition of each element of equal-sized vectors. Due to this ambiguity I assume they decided it was better to rely on the user to call insert diretly.
Operators should be overloaded only when you are not changing the meaning of those operators.*
What that means is, for example, if there is no mathematical definition of the product of two objects, don't overload the multiplication operator for those objects. If there was a mathematical correspondence, operators overloading can make a class more convenient to use by allowing equations to be expressed in the form a*b + c rather than the more verbose (a.multiply(b)).add(c) Where addition and multiplication operators are used, addition and multiplication should be the intent. Any other meaning is more than likely to confuse others. Some other types where overloading operators is acceptable (and, in my opinion, preferable) are smart pointers, iterators, complex numbers, vectors, and bignums.
This follows from one of the design goals of C++, that it should be possible to define classes that are as easy to use as built in types. Of course there are operators you can define on classes which are not mathematical concepts either. You may wish to overload the == and != operators instead of writing an isEqual method, and might want to overload = because the compiler's default assignment operator is not what you want.
On the other hand, overloading an operator to do something unexpected, like defining ^ to translate a string to Japanese, is obscure and dangerous. Your fellow programmers will not be happy to find out that what looked like an exclusive or comparison was actually something very different. The solution then is to write your classes to make it easy to write clear and maintainable code, whether that means using operator overloading or avoiding it.
Adding two vectors is too ambiguous to warrent defining an operator. As others have shown, many people have different ideas of what this means, whereas for a string it is universally understood that adding two strings together means concatenation. In your example, it isn't entirely clear whether you want to do a component wise add on all the elements, add an element to the end, or concat two vectors together. Although it may be more concise to do it that way, using operator overloading to create your own programming language isn't the best way to go.
*Yes, I know Stroustrup overloaded << and >> to do stream operations rather than bitshifts. But those weren't used often compared to arithmetic and pointer operators in the first place, and it could be argued that now that everyone knows how to use cout, it's generally understood that << and >> are the inserter and extractor operators. (He originally tried to use just < and > for input and output, but the meaning of those operators was so ingrained in everyone's minds that the code was unreadable.)
In addition to what others mentioned about this syntax not being intuitive and therefore error prone, it also goes against a good design rule making general algorithms applied to various containers free functions, and container specific algorithms -- member functions. Most containers follow this rule, except std::string, which got a lot of flack from Herb Sutter for its monolithic design.
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.