I'm trying to understand operators in C++ more carefully.
I know that operators in C++ are b开发者_高级运维asically just functions. What I don't get is, what does the function look like?
Take for example:
int x = 1;
int y = 2;
int z = x + y;
How does the last line translate? Is it:
1. int z = operator+(x,y);
or
2. int z = x.operator+(y);
?
When I tried both of them, the compiler errors. Am I calling them wrong or are operators in C++ not allowed to be called directly?
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.
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).
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
.
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);
}
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
.
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.
精彩评论