operator overloading VS template function - c++

I want to write a program that multiplies two 2d arrays. Both arrays are instances of the template class( arrays can be int, float, double). Is it better to overload operators * and = , or to write a function that will multiply arrays? What are the advantages and disadvantages of operator overloading? Does overloading affect the performance of the program?

Overloading operators does not have any performance penalty. It translates to a regular function call. The advantage of operator overloading is only that it makes your code shorter. However, in case of array multiplication, I recommend to use a properly named function because there are at least two kinds of multiplication semantics for vectors - there is element-wise multiplication, and there is dot-product a.k.a. scalar multiplication. An overloaded operator* will leave the meaning obscure.

Related

How to use a Caret "^" in C++ for Exponentiation

I am currently rewriting MATLAB code into C++ code. To have the ability to raise "a" to the power of "b" just by typing "a^b" would make my life so much easier as this is how much of the original code was written in MATLAB.
Is there a way to do this? (I am using primitive types)
I'll happily accept a solution that does NOT involve parenthesis and commas like the pow(a,b) method.
Thanks in advance.
While it is possible to overload ^ to do exponentiation, you shouldn't. It's a bad idea.
#AaronF's answer shows how ugly the code to do this is, but that's only the tip of the iceberg. The real problem comes when you try to actually use this in real code. The problems stem from one simple fact: overloading an operator changes the actions carried out by that operator, but does not affect either the precedence or associativity of that operator. In the case of ^, both the precedence and the associativity are completely wrong for exponentiation.
precedence
In C++, the ^ operator has quite low precedence. Exponentiation should have very high precedence. For example, an expression like x^y*z would normally mean xyz--but what it will mean in C++ is xyz. In fact in C++, ^ has precedence even lower than addition and subtraction, so even x^y+z comes out wrong--it means xy+z instead of the xy+z that you'd want/normally expect.
Associativity
Exponentiation is right associative--but in C++, the ^ operator is left associative. For example, given an expression like x^y^z, what you'd want/expect would be for it to mean xyz, but what you'll get is (xy)z (equivalent to xyz).
Result
These mean that if you do overload operator^ to do exponentiation, you'll only have gotten away from using the name pow. You will not get away from most of the parentheses; in any non-trivial expression, you'll still need parentheses to force the proper precedence and associativity, because as outlined above, the precedence and associativity C++ assigns to operator^ are both entirely wrong for exponentiation.
Conclusion
Although you can overload operator^ to do exponentiation, this is one of those places where discretion is the better part of valor. When you overload operators in C++, you really have three factors to take into account: the name, the precedence and the associativity. For a good operator overload, all three should be right. It's sometimes reasonable to do an overload where only two out of three are right, and the third isn't too far off. In this case, only one out of the three is even close to right; the other two are completely wrong.
Don't do this. It's a bad idea.
The following works, but you have to compile with the c++11 standard (g++ -std=c++11 *.cpp):
You can't use the XOR (^) operator for exponents with primitives. You have to overload it within a class.
#include <iostream>
#include <cmath>
#include <ctgmath>
using namespace std;
class Number {
private:
float _num;
public:
Number(float num) : _num(num){}
Number operator^(const float& num) {
return Number(pow(_num,num));
}
float get() {
return _num;
}
};
int main() {
Number a = Number(5);
Number b = a^7;
cout << b.get();
}
For primitive types (your case) :
In C and in C++, ^ is the bitwise XOR (exclusive-or) operator.
You should use std::pow to raise a number to a power.
For non primitive types, you could however overload operator^ (but it is discouraged since you would go against the usual meaning of this operator)
Example:
MyClass operator^(const MyClass& t1, const MyClass& t2)
{
//return ...
}
You can't do this for primitive types. You'll need to use std::pow. You can do it for user-defined types by overloading the ^ operator, but it may not be a good idea unless XOR makes no sense for your type.
(10 minutes after I say this someone will come up with a horrible, horrible hack for primitive types with a user-defined type, implicit conversions, a user-defined literal, and an overloaded ^ operator.)
pow() in the cmath library. More info on
http://en.cppreference.com/w/cpp/numeric/math/pow
it seems you are looking for someone to say write a^b :D
you should use predefined functions or write a new one ;)

Using / to create a simple rational number object

I have a bunch of data in the form of extremely long equations that includes rational numbers in the form of (a/b) where a and b are integers. I made a simple class that stores rational numbers with corresponding arithmetic operators.
I'm trying to write some code that is able to recognize the form (a/b) and construct an instance of that class with the corresponding numerator and denominator. I would much prefer to conserve the original form of input (a/b). Is it possible to overload the / operator such that (a/b) will return a rational number object? (If not, any ideas for a workaround?)
Example piece of very simplified code:
Param A;
Param B;
(3/5)*A*A + (1/3)*B*B
My Param class has a well-defined multiplication with itself and with the rational number class. I just need the code to recognise (3/5) and (1/3) as instances of a rational number.
No; you can only overload operators if at least one operand is a user-defined type. You can't overload operator/ where both operands are int or any other built-in type.
The closest you can get is rational(a)/b. Whether or not that's better than rational(a,b) is up to your aesthetic judgement.
In C++11 or later, you could muck around with user-defined literals and write things like 3_r/4; but I wouldn't.
No, you can't write Rational operator/(int, int). Because you can't redefine / for ints.
The direct answer is no: operator overload requires at least one user-defined type (otherwise, they would clash with existing operators).
As for workarounds, there are plenty available:
you may use a function: rational(a, b)
you may use a proxy object: MyInt(a) / MyInt(b), this introduces a user-defined type so you can overload the operator / on that type
you may use the C++11 user-defined literals to wrap integers into a proxy class, and overload the operator / on that: 1_i and Rational operator/(MyInt, MyInt)
Which solution you use will depend on the specific constraints you have.

Can we overload operators for built-in types like int or float?

Can we declare a function like this in c++:
int operator + (int , int);
Your answers will be appreciated!
Thanks
You cannot redefine a built-in operator. Operator overloading
is designed to allow you to extend the language, not to change
it. At least one of the parameters of an overloaded operator
must be a user defined type (class or enum type) or a reference
to a user defined type.
Yes: You can pass ints and floats into overloaded functions
No: You cannot overload/override the operators for built in types when the built-in types are on both sides of the expression.
No we cannot overload integer or float types because overloading means to change the working of existing operators or make them to work with objects int is single member not an object.

C++ operator overloading takes pointer type as parameter?

I'm new to C++ and trying to figure out the differences between pointer and reference. I've just read this short summary.
In the article, the author mentioned that day *operator++ (day *d); won't compile (note: day is an enum type) and argued that the parameter for this overloaded operator function must be type T, T&, or T const&, where T is a class or enum type.
I assume that pointer is a built-in type rather than a class or enum so it can't be used to overload operators and that operator overloading is not possible for all built-in types such as int and double.
For example, int i = 1; ++i; would never result in i being 3 by overloading the ++ operator for the type int.
Am I correct? Please help me understand this problem better.
First rule in Operator overloading is:
You cannot overload operators for built-in data types, You can only for your custom data types, So you are correct in that regard.
Yes, pointer are primitive types and not objects. They are just numbers (the memory address of the object they point to), and as such arithmetics can be applied to them.
Yes, you cannot overload operators for primitive types (you can however overload binary operators in a class that take a primitive type parameter).

member binary operator and nonmember binary operator in operator overloading

While trying to learning operator overloading, I read the following statements from C++ Primer. Frankly speaking, I do not quite understand what does the message that these statements want to deliver. The examples include defining both member binary operator and nonmember binary operator. Is there any difference when using them?
Ordinarily we define the arithmetic and relational operators as nonmember functions and we define assignment operators as members:
Sales_item& Sales_item:: operator (const Sales_item&)
Sales_item operator_(const Sales_item&, const Sales_item&);
Both addition and compound assignment are binary operators, yet these functions define a different number of parameters. The reason for the discrepancy is the this pointer.
Yes, there is a difference in actual use. In particular, when you overload an operator as a non-member function, conversions can be applied to either operand (or both operands). When you overload a binary operator with a member function, conversions can only be applied to the right operand.
This can lead to some oddities. For example, consider writing a "bignum" package and you wanted to overload operator+ to handle bignums. If you overload it as a member function, you get an oddity like this:
int x = 2;
bignum y = 3;
bignum z;
z = y + x; // works fine.
z = x + y; // doesn't work: x isn't a bignum, and can/won't be converted to one
If, instead, you overload operator+ using a non-member function, both of the operations will work (presuming you have a constructor to create a bignum from an int, which you'd almost certainly want).
A few operators (particularly assignment operators, such as =, +=, -=, etc.) are special. A conversion creates a temporary object, and assigning to a temporary object 1) isn't allowed, and 2) wouldn't make sense or accomplish much anyway. Therefore, when you're overloading assignment operators, you always use a member function.