I\'m trying to understand operators in C++ more carefully.
I know that operators in C++ are basically just functions. What I don\'t get is, what does the function lo
You can't overload binary operators when both arguments are built in types. However for your own objects this is how you can create them.
//Simple struct that behaves like an int.
struct A
{
int v_;
explicit A(int i) : v_(i) {}
// A member operator so we can write a+b
A operator+(const A & a ) const { return A( v_ + a.v_); }
};
// A non-member operator, so we can write 1+a
A operator+(int i, const A & a)
{
return A(i+a.v_);
}
int main()
{
A a(1);
A b(2);
// Call the member version using its natural syntax
A c = a+b;
//Call the member version using function call syntax
A d = a.operator+(b);
// Call the non-member version using the natural syntax
A e = 1 + b;
// Call the nonmember version using function call syntax.
A f = ::operator+(1,b);
}
For basic types like int
, float
, double
; the operators are already overloaded/pre-defined, so nothing special can be done for that. And,
int z = x + y;
is the only way to express/call it.
For interpretation purpose, actually both the statements,
int z = operator+(x,y);
int z = x.operator+(y);
are true (had it been overloadable).
Using C++ standardese, the function call syntax (operator+(x, y)
or x.operator+(y)
) works only for operator functions:
13.5 Overloaded operators [over.oper]
4. Operator functions are usually not called directly; instead they are invoked to evaluate the operators they implement (13.5.1 - 13.5.7). They can be explicitly called, however, using the operator-function-id as the name of the function in the function call syntax (5.2.2). [Example:
complex z = a.operator+(b); // complex z = a+b; void* p = operator new(sizeof(int)*n);
—end example]
And operator functions require at least one parameter that is a class type or an enumeration type:
13.5 Overloaded operators [over.oper]
6. An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration.
That implies that an operator function operator+()
that only takes int
s cannot exist per 13.5/6. And you obviously can't use the function call syntax on an operator function that can't exist.
Operator overloads only apply to objects and structs, not to fundamental types (such as int or float). If you had an object class like:
class A {
A operator+(const A& rhs) {
return someComputedValue;
}
}
then you can indeed call myA.operator+(anotherA)
and that will be equivalent to myA + anotherA
.
For native types, the operators aren't functions. Only overloaded operators are functions. Built-in operators are built-in - they don't have "functions", they usually just compile down to one or two assembly instructions that it would be insane to call as a function.
So neither operator+(x, y)
nor x.operator+(y)
is correct. I suppose x.operator+(y)
is less correct because non-struct
types can't have members, but I doubt that helps much.
As has been mentioned in commentary and in other answers, by there is no operator+
for fundamental types. For classes, the answer to which of operator+(x,y)
versus x.operator+(y)
is correct is "it depends". Particularly, it depends on how operator+
was defined. If it was defined as an member function then you need to use x.operator+(y)
. If it was defined as a global function then you need to use operator+(x,y)
.
When the compiler confronts the statement z=x+y;
your compiler is smart enough to look for the appropriate form. You shouldn't be expecting one or the other. You should be using x+y
.