Overloading parentheses operator on vector in c++ - c++

I've tried reading several of the overloading questions here to get an idea how to do that, but as I understand overloading parentheses is different from other operators as it needs to be overloaded inside the class?
I have one file in my project, main.cpp, and I'm trying to overload the () operator as follows:
class vector<int> {
public:
bool operator((iterator a);
};
With a matching function.
bool vector<int>::operator()(vector<int>::iterator a) {
return (*a > 0);
}
But I get several errors, the first one being:
an explicit specialization must be preceded by 'template <>' class
vector {
I've tried to correct what the errors ask for, but it seems my understanding of the process is just not good enough.
What would be the correct method of overloading the operator here?
Thanks in advance for any replies.

You have read right: operator() is one of the four operators (along with =, [] and ->) that can only be implemented as class members. And since std::vector is not yours (be it te template itself or any class specialized from it), you cannot implement them for it.
There is still a solution though, and that is to wrap std::vector inside a class of your own, and overload operator() for that:
struct callableIntVector : std::vector<int> {
using std::vector<int>::vector;
bool operator ()(std::vector<int>::iterator a) const {
return *a > 0;
}
};
The usual caveats about inheriting from standard containers apply: don't destruct them polymorphically as they have no virtual destructor, take care not to slice them, etc.

Related

C++ Can I create an interface which calls method implemented specifically in child class, through operator override implemented in the interface?

apologies in advance if this question is stupid but:
I have an interface:
template <class T>
class IEqualCompare {
public:
virtual bool IsEqual(const T b) = 0;
bool operator== (const T b) { return this->IsEqual(b); } //Both are implemented in cpp file
bool operator!= (const T b) { return !(this->IsEqual(b)); }
};
And a class:
class Dimentions : IEqualCompare<Dimentions> {
...
bool IsEqual(const Dimentions b) { //IsEqual logic for this specific class }
...
}
I would like to only implement IsEqual method for each child class of IEqualCompare, as the logic within the operator overloads (==, !=) is the same for any IEqualCompare derived class.
Up until now I have always simply defined both operator overrides as virtual and implemented them inside each class, but as the logic should be always the same I wanted to know if this is possible or is it bad programming.
Thanks in advance for any answers.
First of all, since comparison operators are usually not meant to modify compared objects, they (and IsEqual method) should be declared const as a general practice of const correctness. Among other things it helps programmers avoid mistakes of accidentally modifying objects during semantically non-modifying operations and helps optimizers produce more efficient binaries by utilizing more assumptions about code behaviour. Also, to avoid unnecessary copying the argument of operators should generally be taken by reference, in our case by const reference so that referenced object can't be modified.
Now, if you want to just automatically add equality comparison operators to derived classes based on their IsEqual method and not to use dynamic polymorphism/dispatch (it would be pretty pointless for CRTP base), there's no need to make IsEqual virtual, or even a member of base class at all. Derived type is provided as template parameter type T, so you statically know actual (dynamic) object type (this is the whole point of CRTP pattern you use), thus you can statically cast this pointer to T* and call non-virtual IsEqual method of T through resulting pointer avoiding the more costly virtual dispatch mechanism. Example:
template<typename T>
class AddEqualComparisons {
public:
bool operator==(const T& b) const { return static_cast<T*>(this)->IsEqual(b); }
bool operator!=(const T& b) const { return !static_cast<T*>(this)->IsEqual(b); }
};
class Dimensions : public AddEqualComparisons<Dimensions> {
bool IsEqual(const Dimensions& rhs) const {
// ...
}
};
Your solution is not necessarily bad, it is an application of the "template method" design pattern. It does read like C#/Java-style code to me, which is perhaps unconventional in C++ for this purpose.
The convention in C++ has been to just write each operator!= in terms of operator==. With compilers now supporting C++20, the complementary operator can be generated automatically, removing the need to write a trivial expression like !(x == y). Something like this is often all you need to make your class equality-comparable:
class Foo {
friend bool operator==(Foo const&, Foo const&) = default;
};
If the subobjects of the class (its base classes and member variables) are all equality_comparable, then the above syntax will produce a default comparison operator that compares the two sets of subobjects. You can of course create your own definition if you need to deviate from this.
Note that declaring the operator as a non-member friend function is just my preference, the member function syntax is equally valid.

Why is it recommended to declare functions as "friends" in operator overloading [duplicate]

This question already has answers here:
Operator overloading : member function vs. non-member function?
(2 answers)
Closed 8 years ago.
I have read this at many places which recommend of using "friend" while overload operators but no body explained it clearly as to why it is really needed? Why can not we declare them as plain member function? Any shortcoming?
Googled this but did not get any clear answer.
Sometimes you can't declare operator overload as a member function, like in IO operator<< and operator>>. The first parameter of these functions has to be ostream or istream, which are library classes and you can't extend them, declaring such functions as friend gives them access to private variables of your class.
Using friend means it's a nonmember friend function.
For improving encapsulation by minimizing dependencies, it's better to declare nonmember nonfriend functions. If it need to access the private/protected member of the class, make it friend. At last, make it a member function.
Here's an algorithm to determine whether a function should be a member and/or friend, from [C++ Coding Standards: 101 Rules, Guidelines, and Best Practices By Herb Sutter, Andrei Alexandrescu](Item 44. Prefer writing nonmember nonfriend functions):
// If you have no choice then you have no choice; make it a member if it must be:
If the function is one of the operators =, ->, [], or (), which must be members:
Make it a member.
// If it can be a nonmember nonfriend, or benefits from being a nonmember friend, do it:
Else if: a) the function needs a different type as its left-hand argument (as do operators >> or <<, for example); or b) it needs type conversions on its leftmost argument; or c) it can be implemented using the class's public interface alone:
Make it a nonmember (and friend if needed in cases a) and b) ).
If it needs to behave virtually:
Add a virtual member function to provide the virtual behavior, and implement the nonmember in terms of that.
Else: Make it a member.
In some case, such as above-mentioned a) and b), you can't achieve them by member function, you have to declare them as nonmember function, and make them friend if need to access the private/protected member of the class.
There are a few reasons people use friend:
sometimes granting friendship is actually reasonable, as the public API shouldn't expose some members than need to be compared
it's convenient for a lazy programmer to grant access to all the private and protected data members, ensuring you can write the operator implementation without needing to go back to grant access later or use a less obvious/direct public function (that's NOT a good reason, just a lazy one)
you can define the operator function inside the class, where any template parameters, typedefs, constants etc. don't need to be explicitly qualified as they would in the surrounding [namespace] scope. That's considerably simpler for those new to C++.
e.g.:
template <typename T>
struct X
{
friend bool operator==(const X& lhs, const X& rhs) { ... }
};
...vs...
...struct X as above without ==...
template <typename T>
bool operator==(const X<T>& lhs, const X<T>& rhs) { ... }
in a two-birds-with-one-stone scoop, it makes the function nominally inline, avoiding One Definition Rule complications
Only the first reason above is a compelling functional reason for making the operator a friend, rather than making it a non-member function, given the lesser encapsulation and correspondingly higher maintenance burden involved.
There are excellent reasons though to prefer either a friend or non-friend non-member function to a member function, as an implicit constructor can then kick in to allow the operator to work with one instance of the class and another value from which a second instance can be constructed:
struct X { X(int); };
bool operator==(const X& lhs, const X& rhs);
x == 3; // ok for member or non-member operator==
3 == x; // only works for non-member operator== after implicit X(3) for lhs
You are listing two options only for overloaded operator, while actually there are three:
global function, not friend
member function
global function, friend of the class
You did not list the first one, and yet it is the recommended one. If you can define an operator in terms of existing class public interface, define it as global function outside the class. In this way you do not extend the class public interface without need, minimizing the number of functions with access to the class private members.
What to do if the operator needs to access the class private members? Then you have two options - member function or a friend global function. From those two member function is preferable because it is cleaner. However, in some cases it is not possible to define an overloaded operator as the member function. If the object of your class is right-hand argument to two-argument operator, then global function is the only choice.
I assume that we are comparing global-scope friends that are defined in class and non-friends.
The reasons that the former is sometimes preferred are that such functions...
... need access to the data members for the operation to be performed. This can also be done by loosening encapsulation by providing the data through public getters, but that's not always desired.
... shall only be found via ADL to avoid pollution of some namespaces and overload candidate sets. (Only friend functions that are defined in the class they are a friend of satisfy this!)
Moreover, a minor goodie is that for class templates, it's easier to define a global function that operates on specializations inside them since we avoid making the function a template. Also the function is implicitly inline. All this shortens the code, but is no primary reason.
If your implementation followed proper data encapsulation then you might not exposed your data variables to outside world and all data members will be declared as private.
But using operator overloading most of the times you will be accessing the data members , please note it here you will be accessing the data members outside your class. So to provide access to the data members outside your class it is advised to declare the operator overloaded function as friend.
But this might not be required for unary operators , as it will operate on the data members of the particular class in which it is called.
Let me know if you need any examples for your understanding.
There are serious advantages to non-member functions when dealing with operators.
Most operators are binary (take two arguments) and somewhat symmetrical, and with a member operator they only work if *this is the left-hand side argument. So you need to use a non-member operator.
The friend pattern both gives the operator full access to the class (and, operators are usually intimate enough that this isn't harmful), and it makes it invisible outside of ADL. In addition, there are significant advantages if it is a template class.
Invisible outside of ADL lets you do crazy stuff like this:
struct bob {
template<class Lhs, class Rhs>
friend bob operator+( Lhs&&, Rhs&& ) { /* implementation */ }
}
here our operator+ is a template that seemingly matches anything. Except because it can only be found via ADL on bob, it will only be matched if it is used on at least one bob object. This technique can let you pick up on rvalue/lvalue overloads, do SFINAE testing on properties of types, etc.
Another advantage with template types is that the operator ends up not being a template function. look here:
template<class T>
struct X {};
template<class T>
bool operator==( X<T>, X<T> ) { return true; }
template<class T>
struct Y {
friend bool operator==( Y, Y ) { return true; }
};
struct A {
template<class T>
operator X<T>() const { return {}; }
};
struct B {
template<class T>
operator Y<T>() const { return {}; }
};
int main() {
A a;
X<int> x;
B b;
Y<int> y;
b == y; // <-- works!
a == x; // <-- fails to compile!
}
X<T> has a template operator==, while Y<T> has a friend operator==. The template version must pattern-match both arguments to be a X<T>, or it fails. So when I pass in an X<T> and a type convertible to X<T>, it fails to compile, as pattern matching does not do user defined conversions.
On the other hand, Y<T>'s operator== is not a template function. So when b == y is called, it is found (via ADL on y), then b is tested to see if it can convert to a y (it can be), and the call succeeds.
template operators with pattern matching are fragile. You can see this problem in the standard library in a few points where an operator is overloaded in ways that prevent conversion from working. Had the operator been declared a friend operator instead of a public free template operator, this problem can be avoided.

When an object provides both `operator!` and `operator bool`, which is used in the expression `!obj`?

I've ran across a question I am not able to answer for myself. Also, I didn't find an answer to this on both google and here. Say, I want to "check an object for validity" in an if clause, like so:
MyClass myObject;
// [some code, if any]
if (!myObject)
{
// [do something]
}
Let MyClass be defined something like this:
class MyClass
{
public:
MyClass() { };
virtual ~MyClass() { };
bool operator!()
{
return !myBool;
};
operator bool()
{
return myBool;
};
private:
bool myBool = 0;
};
My question now is: Which one of the overloaded operators is actually used in this if clause? Either way, the result is obviously the same.
It will use operator!.
A function whose parameter types match the arguments will be chosen in preference to one that requires type conversions.
You'll find that operator ! gets executed because it's the most direct resolution. If it used operator bool instead then it would have to call the conversion operator first, and then apply the ! separately to that.
As a general rule, it's a good idea to avoid that situation though. It's generally better just to define the bool conversion, because strictly speaking that's what you want your logical operators to act on, rather than MyClass directly. Defining both creates a bit of a readability problem, and is a form of redundant code duplication (which can lead to programmer error in future).

C++ class operator overloading

It's possible to overload the not operator for a class:
class TestA
{
public:
bool Test;
const bool operator!(){return !Test;}
};
So that...
TestA A; A.Test = false;
if(!TestA){ //etc }
...can work. However, how does the following work?
if(TestA) //Does this have to be overloaded too, or is it the not operator inverted?
I will add, having read it, I am slightly confused by the typedef solution that is employed, and I don't fully understand what is occurring, as it seems somewhat obsfucated. Could someone break it down into an understandable format for me?
You could write an operator bool(). This takes care of coercion to bool, making statements as your above one possible.
You overload operator void* (like the standard library's iostreams) or use boost's trick of using an "unspecified_bool_type" typedef (safe bool). It does NOT automatically invert your operator!

c++ overloaded method in derived class

I have the following question:
Assume base class A with method:
A& operator+(A& a) {...}
I also have a derived class B which overloads (or at least it should so) this method:
A& operator+(B& b) {...}
The problem is that if i want to call something like:
b + a (where b is of type B and a of type A) i get a compile error.
(error C2679: binary '+' : no operator found which takes a right-hand operand of type 'A' (or there is no acceptable conversion)).
Shouldnt that call the base class method? (it looks like it overrides the method..)
If not, why? Is there a way to fix this (dont tell me to overload the method in B with A&)
Sorry i dont give examples in formated text, but i dont know how to format it.
Thanks in advance!
PS Im using Visual studio 2010 beta.
No, it won't call the base class function. Class B has an operator+, it doesn't take the correct parameter, end of story.
You can define operator+ as a free function, not in any class. Perhaps a friend, if it needs to access private data:
A operator+(const A &lhs, const A &rhs) { ... }
B operator+(const B &lhs, const B &rhs) { ... }
Then b + a will call the first operator, as will a + b. b + b will call the second.
Alternatively, you could "un-hide" the base class implementation, by putting this in class B:
using A::operator+;
it's probably best not to, though. Most operators work better as free functions, because then you get automatic conversions on both operands. C++ never performs conversions on the LHS of a member function call.
Btw, operator+ almost certainly should return by value, not by reference, since an automatic (stack) variable no longer exists once the function returns. So the caller needs to be passed a copy of the result, not a reference to it. For this reason operator+ and inheritance aren't a great mix, although it can probably work as long as the caller knows what they're doing.
The problem is called hiding - a member function in a derived class hides functions with the same name in the base class. In this case you can't access A::operator+(A&) because it's being hidden by B::operator+. The way to fix this is to define B::operator+(A&), and possibly have it call the base class function.
Edit: There's a section in the C++ FAQ Lite that goes into more detail about this problem and offers another possible solution, namely the using keyword.
The problem is that you are defining the member operator, so when called as b + a it results in b.operator+( a ), which doesn't exist.
Accepted practice is to define free operators that themselves would call [virtual] members on the arguments.
Edit:Standard example of what I'm talking about is adapting a class hierarchy for output streaming:
class base
{
public:
virtual ~base();
virtual void print( std::ostream& ) const;
};
std::ostream& operator<<( std::ostream& out, const base& b )
{
b.print( out ); return out;
}
This doesn't really work for math operations since you want to return by [const] value, not reference, i.e. avoid nonsense like a + b = c;.
For example, addition of real and complex numbers is defined, but yields complex number as the result, so you cannot derive complex from real. The other way - maybe. But still you want to define exact operations interface:
const real operator+( const real&, const real& );
const complex operator+( const complex&, const complex& );
Hope this gives you enough to re-think your design :)
Couple of things come to mind. First, you would generally want to make the operator + "virtual". Then, the derived operator + taking a reference to B would be an override due to co-variance, instead of hiding the base class implementation, which is what is happening here.
That said, I suspect (but can't say for certain without compiling a test project) that that would actually solve your problem. That's because the standard answer for binary operators is to use static methods that take two parameters on the class. The C++ STL uses this technique extensively, and I don't know of a reason to attempt to implement binary operators as instance methods, virtual or not. It's just too confusing, with no real up-side.