Difference between operator and function in C++? - c++

I could use some help understanding the following in C++, particularly the difference between an operator and a function:
What is an operator?
What is a function?
What is the difference between them?
Is a user-defined operator+() a function or an operator?
Can an operator operate on operands at compile-time? Do they always operate at compile time? (like sizeof() in C++)

An operator is a symbol like +, -, += and so forth (see 13.5). They don't carry a meaning. During semantic analysis, the meaning of an operator is determined.
A function is a constructor, destructor, conversion function (that looks like operator type()) or operator function (function template specialization and instantiation can yield these in turn).
An operator function is something that implements an operator (see 13.5). An example is operator+. These are functions in all respects, and the only difference to "usual" functions is that they may be called implicitly and they have a funny name.
Some operators have a built-in meaning, that can be changed by the programmer. One refers to the built-in meaning of an operator simply by saying built-in operator (see 5/3). However, if such an operator is applied on operands for which a built-in meaning is defined, changing that meaning is only allowed for a few cases (these are assignment, address-of and the comma operator, see 13.5/6).

What is an operator?
An operator is a symbol that is use in expressions.
Examples are: + - * / etc
On built-in types there operations are well defined and unchangable.
For user defined types the operators can be defined as syntactic sugar for a function/method call
Array a;
a = b + c; // a.operator=(b.operator+(c));
What is a function?
We use the term function/method interchangeably most of the time. The only difference is that a method is associated with an instance of a class object. Otherwise they are the same. They provide a way of grouping a set of instructions together.
What is the difference between them?
The action of an operator on a built-in type is defined by the compiler.
The action of an operator on a user defined type is a function call.
Is a user-defined operator+() a function or an operator?
Its a function (or a method). Use of an operator on a user defined type is syntactic sugar for a function call. They are still refereed to as operators though in normal conversation.
Can an operator operate on operands at compile-time?
For built-in types yes. The compiler has extensive ability to optimize there usage.
For user defined types. It can perform optimizations on the operators just like other functions which may lead to there being eliminated, but the code is not executed at compile time.
Do they always operate at compile time? (like sizeof() in C++)
No. sizeof() is relatively unique.
Edit:
To show that operator in user defined class behave just like functions here is an example of using mem_fun_ref
#include <vector>
#include <algorithm>
#include <memory>
#include <functional>
class X
{
public:
// Non standard operators.
// Because std::mem_fun_ref has a known weakness in that it can
// not be used with methods that take parameters be reference.
//
// The principle is the same though. That the operator+ can be
// used anywhere that the add() method can be used.
X& operator+(X* rhs) { return *this;}
X& add(X* rhs) { return *this;}
};
typedef X& (X::*MEMF)(X* rhs);
int main()
{
MEMF p1 = &X::add;
MEMF p2 = &X::operator+;
X value;
std::vector<X> data;
std::for_each(data.begin(),
data.end(),
std::bind2nd(std::mem_fun_ref(&X::operator+),&value));
}

There is no meaningful difference between operators and functions, except that operators have a different syntax. Primitive operators however are not functions.

What is operator?
An operator is generally an operation performed on a variable given some form of punctuation. For example, the default behavior of operator+ between two integers is to add them.
What is function?
A function is a subroutine -- a reuseable block of code.
What is the difference between them?
Nothing, as far as user code is concerned, except for syntax. Note that if you override operator||, operator&&, or (to a lesser extent) operator,, you change the semantics of the built in operator semantics. In the case of && and ||, you make the operation which is normally short circuiting into an operation which is not. In the case of the comma, you would need to ensure that you evaluate the arguments left to right, as the comma operator normally behaves in this way.
Is user-defined operator+() a function or operator?
Neither. It is a user defined operator overload. A function name cannot start with the keyword operator, and an operator is simply the actual punctuation mark used to invoke the operator overload, i.e. + or -. EDIT: Note that while technically speaking it is not a function, it does have the semantics of a function call, as demonstrated in #Martin York's excellent answer.
Can operator operate on operands at compile-time? Do they always operate at compile time? (like sizeof() in C++)
No, sizeof cannot be overloaded. If you want some form of compile time operation done, you need to use something like template metaprogramming. Note that if the compiler is able to do the calculation at compile time it may elide the call into your overloaded operator, of course.

In C++ you can override what the symbols +, -, ==, etc. do when applied to class instances. By defining the "operator+" method in class A, you are telling the compiler what to do with code like:
A a, b, c;
c = a + b; // the + here actually calls a.operator+(b)
It's also a function or more precisely an instance method, in the sense that it's something that gets called.
EDIT: see also http://en.wikipedia.org/wiki/Operator_overloading
and http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading

There is no huge difference between functions and operators. You can think of an using operator, e.g., 'a+b', as a shortcut to the function operator+(a,b) which is defined for the types of a and b. Of course, operators on primitive types (like integers) and a few other exceptions are not necessarily defined like this.
Thus, to answer a few of your specific questions:
Is user-defined operator+() a function or operator?
A function that implements an operator.
Can operator operate on operands at compile-time? Do they always operate at compile time?
Since it is a function, it operates at run time, but in some cases compiler optimizations can do work at compile time for certain operators. I'm not 100% sure why you're asking this, so perhaps there is something I'm not aware of here.

There are only two minor differences between functions and operators.
Operators can be used in two ways (x+y or operator+(a,b)).
Operators must have same number of parameters as the built-in one (operator== must have exactly two params). The exception from this rule is function call operator() which can be overloaded with any number of any parameters.

Here are some differences between an operator and a function:
An operator does not push its parameters onto the stack, but a function pushes its parameters onto the stack.
The compiler knows about the operation of the operators, but is not aware of the output of the function. Said a different way, the action of the operator is defined at compilation time and that of a function is defined at the runtime.

Related

C++: Member Overloading Binary Operators which Modify the Left Operand eg +=

I'm learning about Operator Overloading at the moment on learncpp.com and came across a statement that I can't quite wrap my head around. Here it is:
When dealing with binary operators that do modify the left operand
(e.g. operator+=), the member function version is typically preferred.
In these cases, the leftmost operand will always be a class type, and having the object being modified become the one pointed to by
*this is natural. Because the rightmost operand becomes an explicit parameter, there’s no confusion over who is getting modified and who
is getting evaluated.
I don't understand why the left hand operand will always be a class type. If I were overloading +=, for example, why couldn't I overload with the user defined class as the righthand parameter, like below?
void operator+=(int blah, MyNewClass foo);
Thanks in advance!
Despite the comments, you read this correctly: it’s talking about all such modifying operators, and it’s using the statement about the left-hand operand to justify the idea of a member function being “typically preferred”. (If it’s going to be a class-type object, you definitely have the opportunity to use a member function, and we generally prefer to express modifications to such objects in terms of member functions.)
The passage simply doesn’t consider the esoteric possibilities of overloading with non-member functions:
enum nil {};
// Use left-to-right compound assignment:
void operator+=(const int &i,nil &n)
{n=static_cast<nil>(n+i);}
// Make something into a pointer (*):
template<class T>
void* operator*=(T &t,nil) {return &t;}
struct A {operator int();};
// Convert sum to a percentage (%):
double operator%=(A a,A b) {return (a+b)/100.;}
// Infix call notation (like $ in Haskell):
template<class R>
R operator&=(R f(int),A a) {return f(a);}
Very occasionally someone might find a clever way of using, say, >>= in this fashion to emulate Haskell, but for someone just learning the language (to whom that passage is certainly addressed), perhaps the very possibility of such examples is best left unsaid. (Forget I said anything.)

operator& that returns an int and operates on 2 vectors?

I would like to define an & operator between two std::vector<int>. This operator should bit-wise and each element of both vectors together and return the number of non-zero components of the resulting vector.
However, if I define int operator&(const std::vector<int> &lhs, const std::vector<int> &rhs), it the compiler doesn't like it and requires operator& to return a boolean. Is this actually a restriction with operator&?
I would like to define an & operator between two std::vector<int>.
You may not (at least not globally; it can in theory be done in a custom namespace but I recommend against it). Operator overloads for standard templates with no user defined type arguments are reserved to the standard library.
I recommend writing a regular function instead.
Any idea why there's that restriction?
Because this restriction allows the standard library to change and add any operator overload that the committee wishes without breaking previously well defined programs that have their own conflicting overloads (by virtue of not allowing such overloads to be defined).
operator& to return a boolean. Is this actually a restriction with operator&?
No. This is actually not a restriction of binary operator&. It may return int.

Why would you want to overload operators and how can you use its original functionality?

I am having trouble trying to understand why someone would want to overload an operator. I understand it can help reassign functionality, but it takes away key functionalities as well.
In an assignment given to me, I was given a skeleton code that Vector4f overloaded =, and now in Matrix4f.h, I can't use = when creating a function to turn a matrix into an identity matrix (the matrix is set to a float, not int).
Is the original functionality lost, or do I need to type cast the = somehow? Also, why is even reassigning core functionality operators a good idea? My professor had suggested that we could have done add() and overloaded that, but didn't.
Operator overloading is a way of adding some syntactic sugar to help your types have a full, semantically-coherent API.
Take, for example, std::string. In terms of pure assignment operators, it provides a number of ways to help the string behave in a coherent and semantically-sound way. In addition to the copy/move operator= overloads, it supplies:
operator=(CharT): Assign to a character
operator=(const CharT*): Assign to a string-literal or pointer to C-style string
Which allow it to behave in a way that the consumer would expect, such as:
auto str = std::string{""};
str = "hello world"; // c-style string/string literal
str = 'c';
Other operators in this example would be:
operator+(const CharT*): append c-strings/string literals
operator+(CharT): append characters
operator+(const basic_string&): append other std::strings
Equality or comparison operators (operator==, operator<, etc): comparing things in a coherent way
Adding operators doesn't remove functionality. It helps to extend the functionality by providing a semantically clear way of writing code.
Note: The assignment operator is a special case, in that some circumstances may result in the compiler-generated operator= to be deleted. However, you can always define it by-hand, or explicitly use the = default syntax to re-enable it. For example:
class Foo
{
public:
...
Foo& operator=(const Foo&) = default; // Explicitly ask for the compiler-generated one
};
Languages that do not support operators like this may result in having to write code with everything written out. For example:
string("hello").append(' ').append("world")
instead of simply
std::string{"hello"} + ' ' + "world";
(these are contrived examples)
Edit: The answer above focuses more on your immediate question as to why to overload operators. Your error, as seen in your screenshot, appears to be due to a lacking operator= overload for assigning an int (or some other numerically convertible type, like a float) to the Vector4f type. Defining a custom operator would enable this.

How to make operators work from the left of the object?

This feels like too basic a question to not have asked already so if it's already out there I'd accept the link as the answer or delete this post if you fellas see fit, personally I couldn't find it anywhere at least so perhaps this'll be useful to others...
So yeah, like it's said in the title, how do I make operators that'd let me work from the left side of the object? f.e:
++obj
variable * obj
etc
If I wanted to work on the right side of that 'obj' I'd make something like
obj operator*(const variable &t){...} //for obj * variable operation
intuitively I tried
obj *operator(const variable &t){...} //for variable * obj operation(?)
to make it work the other way around but of course, that didn't work, any suggestions?
Ummm you cannot do that. I mean, choose which side the operator works on. It is defined by the standard. The operators in c++ do not have sides they operate on. All are different operators. The operator you overload is defined by the signature.
The "side" has meaning only for the unary operators anyway. For binary operators it is either a member function called on the left operand, with right operand passed as an argument, or a free standing function.
The case that "allows definition of the side" is ++ and --. And it is a special case. ++c and c++ are actually two different operators in terms of language -- pre- and post- incrementation. The differentiation between realized by a "bogus" parameter in the overload: http://en.cppreference.com/w/cpp/language/operator_incdec.
There are other unary operators too, and you cannot choose side E.g: !, ~, there are no suitable overloads defined for "right side" cases.
Other disambiguation is also done via parameters. * used for both, member access and arithmetic operation. The operator which you overload is defined by number of parameters.
T T::operator*(const T2 &b) const; is artithmetic one, and R& T::operator*(); is member access.
Here you can find rules for all operators: http://en.cppreference.com/w/cpp/language/operators.
Aaand since its c++ you can abuse it. Unrecommended though.
You can overload function and make that function friend of the class.
variable operator*(const variable &, const variable *);
class variable {
friend variable operator*(const variable &, const variable *);
};

Overload an Operator C++ in given class being the operators from a Different Class

I have a function multiply and a function sum, with special characteristics, implemented on a given class i.e. (EngineManager). These functions add and multiply integers in a special fashion and they give away as a result a different class i.e. (StandardShare). When I try to implement the overload directly, the compiler promts:
Overloaded 'operator+' must be a unary or binary operator (has 3 parameters)
I understand that the third parameter it is referring to is the this pointer. But as I cannot implement them as free methods, given that they use functions from the hos class i.e. (EngineManager), what alternative do i have.
The code should look like this:
class EngineManager {
public function Shares::StandardShare* addShares(int a, int b){
//Does Something......
};
inline Shares::StandardShare* operator +(int a, int b){
return this->addShares(a,b);
};
};
Thanks in advance
This is neither possible, nor a good idea.
It's not possible not only because overloading the + operator that takes two arguments must be a free function, but also because the type of both arguments cannot be a simple built-in type (like int). At least of them must be a class or enumerator type.
It's not a good idea because, even if it were possible, the effect of this would not be confined to the class. The overloaded operator would be called everywhere where you include the header file of your class. So suddenly all integer additions across your program would break. But most importantly, it's not a good idea because it breaks the intuitive meaning of using the + operators with two integers. If you change that meaning, you're only creating confusion for no good reason.