With in a class if we are using both member function and friend function to overload + operator its giving an error that ambiguous overload for ‘operator+’ how to resolve
I would suggest implementing it as a non-member function. That way, you can overload the function with other combinations. As an example, let's say you have a class Point and another class Vector (a gometric vector, not the std::vector).
You can overload
Point operator+(Point const&, Vector const&);
Point operator+(Vector const&, Point const&);
If you implement it as a member function, you implement only one of them in a class. To implement both, you'll have to implement the first one as a member function of Point and the second one as a member function of Vector.
You could have a member and non-member overload of operator+, if you really wanted to.
Foo a, b;
a.operator+(b); //call member function
operator+(a, b); //call non-member function
It ruins the whole point of operators, though, since you have to actually write out the method call.
Side note: non-member operator+ doesn't need to be a friend function. It's easily written as:
Foo operator+ (Foo lhs, const Foo& rhs)
{
return lhs += rhs;
}
Related
Suppose we have this class definition:
class A{
public:
int a;
A(int i): a(i){}
A operator-() const { return A(- a); } # first operator- function
};
A operator-(const A& o) { return A(- o.a); } # second operator- function
Now, in the main function, if I write:
A a1(10);
A a2 = -a1; # Here the first operator- function (method) is called!
However, if I remove the first definition of operator- in the class, the second function is called.
I would llike to know why the compiler prefers the first definition when both of them are provided.
I would like to know also why the compiler accept to call the first function (method). Because I think that the method is synonym to a1- and not -a1 : The object on which the method is applied comes before (at the left of) the operator.
From the C++ standard, unary minus operator shall be defined like this:
T T::operator-() const;
inside class definition, and like this:
T operator-(const T &a);
outside class definition.
Now, you have both definition types in your class, so there member lookup comes in a play as specified here:
two separate lookups are performed: for the non-member operator
overloads and for the member operator overloads (for the operators
where both forms are permitted). Those sets are then merged with the
built-in operator overloads on equal grounds as described in overload
resolution. If explicit function call syntax is used, regular
unqualified name lookup is performed
So, basically, member lookup finds A operator-() const;, non-member lookup finds A operator-(const A& o);. Overload resolution selects A operator-() const;.
This question gives a good answer why to define operator overloads as non-members: Operator overloading : member function vs. non-member function?
If you define your operator overloaded function as member function,
then compiler translates expressions like s1 + s2 into
s1.operator+(s2). That means, the operator overloaded member function
gets invoked on the first operand. That is how member functions work!
But what if the first operand is not a class? There's a major problem
if we want to overload an operator where the first operand is not a
class type, rather say double. So you cannot write like this 10.0 +
s2. However, you can write operator overloaded member function for
expressions like s1 + 10.0.
Now I have a situation where I need to overload operator==. In my case, only (a) objects of (b) the same type will be compared.
Is there a reason to still define operator== as a non-member or should I implement it as a member in that case?
Because operator== has symmetric semantics for its LHS and RHS argument, the recommended approach is to always implement it as a non-member in terms of the public interface of its operands (or if private data is required, to declare it as a friend inside the class).
So
class Bla
{
public:
// complete interface to data required for comparison
auto first();
auto second();
// ... more
private:
// data goes here
};
bool operator==(Bla const& L, Bla const& R)
{
return
std::forward_as_tuple(L.first(), L.second() /*, ... */) ==
std::forward_as_tuple(R.first(), R.second() /*, ... */)
;
}
This way, implicit conversion to Bla are considered for both the L and R arguments (I'm not saying implicit conversions are a good idea, but if you have those, it's better to avoid surprises where they are only considered for the RHS argument).
I want to overload the * operator for a class, one which is in case it is multiplied by a real number double and the other is when multiplied by the same class type.
Below is my code:
class Vector2D {
...
friend Vector2D operator* (const Vector2D&);
friend Vector2D operator* (const double); // getting error here
};
The error I'm getting is: 'Vector2D operator*(double)' must have an argument of class or enumerated type
Is it possible to overload operators more than once, and if so, why am I getting an error?
class Vector2D {
...
friend Vector2D operator* (const Vector2D&);
That is overloading unary operator* (i.e. dereference operator) as a free function, not overloading the multiplication of two vectors. You cannot overload operators that apply only to non-class types, and that is the error for:
friend Vector2D operator* (const double);
You probably meant to write:
friend Vector2D operator*(const Vector2D&,const Vector2D&);
friend Vector2D operator*(const Vector2D&,double);
The problem is that you're overloading unary operator*, not binary. Your friend declarations are not member functions.
Either remove the friend (if you want to overload the operators as member functions), or else add a first parameter of type const Vector2D& or Vector2D& (if you want to overload as free functions). The latter is usually preferable, since then you get implicit conversion on both arguments -- member operator overloads will implicitly convert the right hand side but not the left.
The reason you might not want a reference as the first argument to binary operator*, is so that you can implement it like this:
Vector2D operator*(Vector2D lhs, const Vector2D &rhs) {
lhs *= rhs;
return lhs;
}
The same would apply to addition (and addition of two vectors makes sense to me in a way that multiplication of two vectors does not).
You are not allowed to override the operators for built-in types. In this case you're providing a declaration for a unary * operator for type double which isn't allowed.
I think you want to remove the friend declaration and make these member functions instead.
I read that an overloaded operator declared as member function is asymmetric because it can have only one parameter and the other parameter passed automatically is the this pointer. So no standard exists to compare them. On the other hand, overloaded operator declared as a friend is symmetric because we pass two arguments of the same type and hence, they can be compared.
My question is that when i can still compare a pointer's lvalue to a reference, why are friends preferred? (using an asymmetric version gives the same results as symmetric)
Why do STL algorithms use only symmetric versions?
If you define your operator overloaded function as member function, then the compiler translates expressions like s1 + s2 into s1.operator+(s2). That means, the operator overloaded member function gets invoked on the first operand. That is how member functions work!
But what if the first operand is not a class? There's a major problem if we want to overload an operator where the first operand is not a class type, rather say double. So you cannot write like this 10.0 + s2. However, you can write operator overloaded member function for expressions like s1 + 10.0.
To solve this ordering problem, we define operator overloaded function as friend IF it needs to access private members. Make it friend ONLY when it needs to access private members. Otherwise simply make it non-friend non-member function to improve encapsulation!
class Sample
{
public:
Sample operator + (const Sample& op2); //works with s1 + s2
Sample operator + (double op2); //works with s1 + 10.0
//Make it `friend` only when it needs to access private members.
//Otherwise simply make it **non-friend non-member** function.
friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}
Read these :
A slight problem of ordering in operands
How Non-Member Functions Improve Encapsulation
It's not necessarily a distinction between friend operator overloads and member function operator overloads as it is between global operator overloads and member function operator overloads.
One reason to prefer a global operator overload is if you want to allow expressions where the class type appears on the right hand side of a binary operator. For example:
Foo f = 100;
int x = 10;
cout << x + f;
This only works if there is a global operator overload for
Foo operator + (int x, const Foo& f);
Note that the global operator overload doesn't necessarily need to be a friend function. This is only necessary if it needs access to private members of Foo, but that is not always the case.
Regardless, if Foo only had a member function operator overload, like:
class Foo
{
...
Foo operator + (int x);
...
};
...then we would only be able to have expressions where a Foo instance appears on the left of the plus operator.
I am currently creating a utility class that will have overloaded operators in it. What are the pros and cons of either making them member or non-member (friend) functions? Or does it matter at all? Maybe there is a best practice for this?
I'd go with "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices": if you can do it as non-member function, do it as non-member function (in the same namespace).
One of the reasons: it works better with implicit type conversion. An Example: You have a complex class with an overloaded operator*. If you want to write 2.0 * aComplexNumber, you need the operator* to be a non-member function.
Another reason: less coupling. Non-member-functions a less closely coupled than member functions. This is almost always a good thing.
Each operator has its own considerations. For example, the << operator (when used for stream output, not bit shifting) gets an ostream as its first parameter, so it can't be a member of your class. If you're implementing the addition operator, you'll probably want to benefit from automatic type conversions on both sides, therefore you'll go with a non-member as well, etc...
As for allowing specialization through inheritance, a common pattern is to implement a non-member operator in terms of a virtual member function (e.g. operator<< calls a virtual function print() on the object being passed).
If you plan on implementing streaming operators (<< and >>) then they will be non-members methods because your object is on the left of the operator.
If you plan on implementing ->, () or [] they are naturally member methods.
For the others (comparison and mathematical) you should check out Boost.Operators, it really helps.
For example, if you want to implement the following operators:
MyClass& MyClass::operator+=(int);
MyClass operator+(const MyClass&, int);
MyClass operator+(int, const MyClass&);
You only have to write:
class MyClass: boost::operator::addable<MyClass,int> // no need for public there
{
public:
MyClass& operator+=(int);
private:
};
The 2 operator+ will be automatically generated as non-members which will let you benefit from automatic conversions. And they will be implemented efficiently in term of operator+= so you write code only once.
For binary operators, one limitation of member functions is that the left object must be of your class type. This can limit using the operator symmetrically.
Consider a simple string class:
class str
{
public:
str(const char *);
str(const str &other);
};
If you implement operator+ as a member function, while str("1") + "2" will compile, "1" + str("2") will not compile.
But if you implement operator+ as a non-member function, then both of those statements will be legal.
If you are implementing op, then most probably you need to implement op=. i.e. if you are overloading + operator, then you should implement +=.
Make sure that you are returning const to an object if you are doing post-increment or overloading + operator.
So, if you overload operator + , then implement it as a non-member operator and use += operator inside it. For eg.
const A operator+(const A& lhs, const A& rhs)
{
A ret(lhs);
ret += rhs;
return ret;
}
There is nothing like best practices but it depends on the operator you are overloading ..
For e.g .
>> and << can't be overloaded as member functions .
Suppose you want to do like this : obj1 = 2 * obj2 then go for non-member function.
For binary operator overloading member function takes only 1 parameter (invoking object is impcliitly passed ) whereas non-member function takes 2 parameters .