How can I define operator ** such that it can perform exponentiation of 2 numbers . eg 2 ** 3. It should give answer as 8.
Or Indirectly is there any way I can do this with operator overloading instead of #define macros ?
You can't. You can only overload existing operators, and not for built in types.
You can't. You can only overload existing operators in C++; you cannot add new ones, or change the arity or associativity of existing operators. Even the preprocessor is powerless here - its identifiers cannot be symbols.
If you're willing to make a compromise w.r.t. ** and feel like obfuscating your code:
#include <cmath>
#include <iostream>
struct foo {
foo(int i) : i_(i) {}
int operator*(int exp)
{
return std::pow(i_,exp);
}
private:
int i_;
};
struct bar {
} power_of;
foo operator*(int i, bar)
{
return foo{i};
}
int main()
{
std::cout << 2 *power_of* 3; // prints 8
}
Otherwise, just use std::pow.
Like the other answers noted, this isn't possible for built-in types BUT you can get this to work for custom types like so (minimum code sample):
#include <cmath>
#include <iostream>
struct dummy;
struct Int
{
int i;
Int() : i(0) {}
Int(const int& i) : i(i) {}
dummy operator*();
};
struct dummy
{
Int* p;
dummy(Int* const p) : p(p) {}
int& operator*()
{
return p->i;
}
};
dummy Int::operator*()
{
return dummy(this);
}
int operator*(const Int& lhs, const dummy& rhs)
{
return std::pow(lhs.i, rhs.p->i);
}
int main()
{
Int a(2);
Int b(2);
std::cout<< a ** b << std::endl;
}
Live example
As others have noted: that isn't possible. You can overload another operator, like ^, for exponentiation, instead however on a simple type wrapper class/object.
But, if you're adventurous, another way, is to create a micro DSL that supports on-the-fly calculation of such an operator. (A famous example of that is LISP in C++)
However, given the effort involved, it may or may not be your cup of tea. However, it's worth knowing that such a possibility exists.
UPDATE:
Operator-Overloading works by overloading already existing operators. Why? Because if you could define your own, you will also have to define the precedence of such operators which can easily give way to abusing operators by abstracting away their original purpose - which increases difficulty when reading code. (At least that's the argument that's been made).
The closest operator that has a semantic meaning close to ** is the caret operator. A naive and illustrative implementation of such an operator is:
#include <iostream>
#include <cmath>
class Int {
public:
Int() {}
Int(int i) : value(i) {}
friend double operator^(const int& i, const Int& integer);
friend double operator^(const Int& integer, const int& i);
friend double operator^(const Int& lhs, const Int& rhs);
private:
int value;
};
double operator^ (const int& lhs, const Int& rhs) {
return std::pow(lhs, rhs.value);
}
double operator^ (const Int& lhs, const int& rhs) {
return std::pow(lhs.value, rhs);
}
double operator^ (const Int& lhs, const Int& rhs) {
return std::pow(lhs.value, rhs.value);
}
int main() {
Int i1 = 10;
Int i2 = 3;
double result = i1 ^ i2;
std::cout << result;
return 0;
}
Unfortunately the set of operators that can be overloaded in C++ is fixed and does not include the ** operator. You might think of using operator^() instead, but it turns out that ^ has the wrong precedence to serve as an exponentiation operator.
In short, there's not much you can do about this, unfortunately.
You can't overload operators for built-in types. I'd use operator ^ for such purpose for custom types.
Related
Suppose we have an operator/ on custom class:
struct my_class {
uint64_t value;
}
template<class T>
constexpr T operator/(const my_class& a, const my_class& b)
{
return static_cast<T>(a.value) / static_cast<T>(b.value);
}
How can one select a / b (where a and b are of my_class type) to return int or double, for example?
You could with a bit of template magic and conversion operators. You can first define a simple wrapper for your expression:
struct DivideMyClass {
DivideMyClass(const MyClass& lhs_, const MyClass& rhs_) : lhs{lhs_}, rhs_{rhs} {}
template<typename T>
operator T () const {
return static_cast<T>(lhs.value) / static_cast<T>(rhs.value);
}
private:
const MyClass& lhs;
const MyClass& rhs;
};
Then, overloading the operator can be done like this:
constexpr DivideMyClass operator/(const my_class& a, const my_class& b)
{
return DivideMyClass{a, b};
}
Then your code will look like this:
double d = MyClass{21} / MyClass{5}; // will be equal to 4.2
Why this solution is bad
The language is not overloading division by the return type. You code will confuse other thinking there's a bug. If you use this method extensively, you will end up in an alomost unreadable code.
Another thing, the conversion is done implicitely, and there's nothing that says if there really was a conversion done in the operator on call site.
You will prevent the AAA idom (Almost Always use Auto). auto may break your code, and it's a bad thing.
Techniques like this should be use for template expression and stuff like that. Using that for simple division will confuse other.
Can I select based on type of variable accepting the result? I.e. int
result = a/b returns int, but double result = a/b returns double?
If you are hell-bent on doing this you can, but it's complicated and I wouldn't recommend it. You have to careful weight the benefits vs the complexity introduced. You can do this via lazy evaluation:
struct X {
int value;
};
struct X_op_proxy {
const X& lhs;
const X& rhs;
template <class T>
operator T() const { return static_cast<T>(lhs.value) / static_cast<T>(rhs.value); }
};
auto operator/(const X& lhs, const X& rhs) -> X_op_proxy
{
return {lhs, rhs};
}
int main()
{
X x1{11}, x2{2};
int i = x1 / x2;
cout << i << endl;
float f = x1 / x2;
cout << f << endl;
}
This is the minimum so you can figure out what this technique is about. You can adapt it and grow it to your needs.
To choose a specific operator template, you must call it as a function:
auto result = operator/<double>(my_class{4}, my_class{2});
// result is 2.0
It was very hard to come up with a title... (I'm not a native English speaker.)
struct A
{
int value;
A operator+(int i) const
{
A a;
a.value=value+i;
return a;
};
};
int main(){
A a;
a.value=2;
a=a+2;
return 0;
}
This code compiles/works as expected, but when I change a=a+2 to a=2+a, it won't compile anymore.
GCC gives me this error:
no match for ”operator+” in ”2 + a”
Is there any way to somehow make 2+a work just like a+2?
You need a free function, defined after the class
struct A
{
// ...
};
A operator+(int i, const A& a)
{
return a+i; // assuming commutativity
};
also, you might consider defining A& operator+=(int i); in A an implement both versions of operator+ as free functions. You might also be interested in Boost.Operators or other helpers to simplify A, see my profile for two options.
Sure, define the inverse operator outside the class:
struct A
{
int value;
A operator+(int i) const
{
A a;
a.value=value+i;
return a;
};
};
//marked inline to prevent a multiple definition
inline A operator+(int i, const A& a)
{
return a + i;
}
The other answers here work fine. However, another option you have is to create a constructor for a single int like this:
struct A
{
int value;
A(int i) {
value = i;
}
};
This allows integers to get implicitly converted, and allows you to only overload operators for your struct instead:
A operator+(const A& other) const
{
// All you need to do is work with an A, and associativity works fine
};
Of course, this does allow all integers to get implicitly converted to As, which may or may not be desirable.
I have such code
class Number
{
int m_value;
public :
Number(const int value) :
m_value(value)
{
}
operator const int() const
{
return m_value;
}
int GetValue() const
{
return m_value;
}
};
bool operator==(const Number& left, const Number& right)
{
return left.GetValue() == right.GetValue();
}
class Integer
{
int m_value;
public :
Integer(const int value) :
m_value(value)
{
}
operator const int() const
{
return m_value;
}
bool operator==(const Integer& right) const
{
return m_value == right.m_value;
}
bool operator==(const int right) const
{
return m_value == right;
}
int GetValue() const
{
return m_value;
}
};
bool operator==(const int left, const Integer& right)
{
return left == right.GetValue();
}
int main()
{
Number n1 = 1;
Number n2 = 1;
int x3 = 1;
n1 == n2;
n1 == x3; // error C2666: 'operator ==' : 3 overloads have similar conversions
x3 == n1; // error C2666: 'operator ==' : 2 overloads have similar conversions
Integer i4 = 1;
Integer i5 = 1;
i4 == i5;
i4 == x3;
x3 == i4;
return 0;
}
For class Number I have two errors as shown in the code above. For class Integer everything is OK. The problem is, I want to keep in resulting class single-parameter constructor, cast operator and equality operations (MyClass == int, int == MyClass, MyClass == MyClass), but I want to implement only one version of operator== as in class Number. I don't see any way to do this. Is that even possible or I must have all three implementations as in class Integer? I know why I get these errors I just don't like the solution I have.
In class Number you define a conversion operator to int and your constructor allows converting an int to a Number. Therefore, when comparing a Number n and an int x for equality, ambiguity arises: should the compiler invoke the built-in operator == for ints and convert n to an int, or should it rather pick your operator and convert x to a Number? Both conversions are equally good, and it can't choose one.
So yes you have to define three versions, or add a template operator which can perfectly match the type of all arguments and forward to your operator explicitly, like this one (but you most likely want to guard it with some enable_if to limit its applicability only to the appropriate T and U):
template<typename T, typename U> // beware: this will match anything. to be constrained
bool operator == (T n, U const& u)
{
return (Number(n) == Number(u));
}
You can define only one operator== as member function:
bool operator==(const int& right) const
{
std::cout << "custom\n";
return this->GetValue() == right;
}
Then,
n1==n2: n2 will be converted to int and custom operator will be used.
n1 == n3: custom operator will be used
n3==n1: built-in operator will be used
Note, that you want your operator== be const to be able to compare constant Numbers
In C++11 you can make operator int explicit.
Another approach would be to use SFINAE to have a template == that works for one or more Number args, but that is using a bazooka to kill an ant.
If I have the following files, I get this error (c2593 in VC9).
If I un-comment the prototype in main.cpp, the error disappears. I need to maintain the same functionality while keeping the class out of main.cpp. How can I do that?
Thanks.
main.cpp:
#include "number.h"
//const Number operator + (const Number & lhs, const Number & rhs);
int main(void)
{
Number n1(2); // n1 = 2
Number n2(9,3); // n2 = 3
Number n3 = n1+n2; // n3 = 5
}
number.h:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
};
number.cpp:
#include "Number.h"
const Number operator + (const Number & lhs, const Number & rhs)
{
Number tmp;
tmp.num = lhs.num + rhs.num;
return tmp;
}
Try putting the prototype in the Number header file:
number.h:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
};
const Number operator + (const Number & lhs, const Number & rhs);
number.cpp:
#include "Number.h"
const Number operator + (const Number & lhs, const Number & rhs)
{
Number tmp;
tmp.num = lhs.num + rhs.num;
return tmp;
}
main.cpp:
#include "number.h"
int main(void)
{
Number n1(2); // n1 = 2
Number n2(9,3); // n2 = 3
Number n3 = n1+n2; // n3 = 5
}
You never declare operator + in number.h, you only define it in number.cpp - therefore, when you include number.h in main.cpp, it doesn't know where to go to find operator +.
You must put the declaration of operator + in number.h, outside of the class, then define it in number.cpp
That commented line should go in number.h
EDIT: in number.h but as a free function.
One other thing to note with your code before you go back to us with a very similar question: Better remove the operator int and operator double functions. They will cause you major headache. Let's make a few examples:
Number a, b;
1 + b;
// ambiguous: operator+(int, int) or
// operator+(Number, Number) ?
// did you intend to use those for this case?
float x = a;
// ambiguous: from int -> float or
// double -> float ?
In the original situation you had, your addition was ambiguous, because there were operator+(double, double) and operator+(int, int) builtin operators considered and they were equally well. Others solved that problem. But before you start and run into these other problems, better remove the conversion functions and insert explicit functions like asDouble or something similar.
Apart from other's answers to declare operator+ in the header file, I suggest you to have operator+= in your struct as well.
struct Number
{
// your other declarations.
Number& operator+=(const Number& other)
{
this->num += other.num;
return *this;
}
};
const Number operator+(const Number& lhs, const Number& rhs)
{
Number ret(lhs);
ret += rhs;
return ret;
}
This way it is efficient to call x += y; instead of x = x + y;
Personally I like it better to declare the operators inside the class:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
Number operator+(const Number &arg) const;
};
and then:
Number Number::operator+(const Number &arg)
{
...
}
I am learning C++ and I was wondering if I could gain some insight into the preferred way of creating binary operators that work on instances of two different types. Here is an example that I've made to illustrate my concerns:
class A;
class B;
class A
{
private:
int x;
public:
A(int x);
int getX() const;
int operator + (const B& b);
};
class B
{
private:
int x;
public:
B(int x);
int getX() const;
int operator + (const A& A);
};
A::A(int x) : x(x) {}
int A::getX() const { return x; }
// Method 1
int A::operator + (const B& b) { return getX() + b.getX(); }
B::B(int x) : x(x) {}
int B::getX() const { return x; }
// Method 1
int B::operator + (const A& a) { return getX() + a.getX(); }
// Method 2
int operator + (const A& a, const B& b) { return a.getX() + b.getX(); }
int operator + (const B& b, const A& a) { return a.getX() + b.getX(); }
#include <iostream>
using namespace std;
int main()
{
A a(2);
B b(2);
cout << a + b << endl;
return 0;
};
If I would like to have symmetry among the two types, which method is the best approach in the above code. Are there any possible dangers in choosing one method over the other? Does this vary with the return type? Please explain! Thank you!
The best way is to define (outside of either class) int operator+ (const A& a, const B& b), and make it a friend function of both classes if needed. In addition, define
int operator+(const B& b, const A& a) {return a + b;}
To make it symmetric.
The big risk with this approach is that people tend to perceive + as a symmetric operator. The way this is written, it is not (unless your implementations re the same).
At a minimum, you should overload + as an external binary operator (not as a member), and then play with overloading it several times.
You have to be careful, though, to make sure that nothing becomes ambiguous.
Can you explain what you're trying to do? I can't think of many cases of different types where it makes sense to have the symmetric heterogenous operators.
The main argument for method 2 is that you get implicit type conversion on both operands, not just the second one. This might save confusion somewhere down the line.
Speaking of which, your example code defines implicit conversions from int to A and from int to B, via the 1-arg constructors on both classes. This could result in ambiguity later. But if you left out the "explicit" for brevity, fair enough.
I agree with Uri's warning, though: if you find yourself doing this, you may be writing an API that others will find confusing. How come an A plus a B is an int? Does it really make things easier for users that they are adding a and b, rather than calling getX themselves and adding the results?
Is it because users know perfectly well that A and B are wrappers for ints? If so, then another option is to expose conversions from A to int and B to int, via operator int(). Then a+b will return an int for a sensible reason, and you'll get all the other arithmetic operators too:
#include <iostream>
struct A {
int x;
explicit A(int _x) : x(_x) {}
operator int() {
return x;
}
};
struct B {
int x;
explicit B(int _x) : x(_x) {}
operator int() {
return x;
}
};
int main() {
A a(2);
B b(2);
std::cout << a + b << "\n";
std::cout << a - b << "\n";
}
I read in a comment that your intended use is adding vectors and matrices. Maybe you should consider using only matrices where vectors are one dimensional matrices. Then you are left with just one type and one set of operators:
matrix operator*( matrix const& a, matrix const& b );
matrix operator+( matrix const& a, matrix const& b ); // and so on
If you want to keep the vector class then you should consider whether you also want a transposed vector (maybe transpose is just an internal property of vector).
The set of operations is not really symmetric:
vector * matrix = vector
matrix * vector_t = vector_t
matrix * matrix = matrix
vector_t * vector = matrix
vector * vector_t = int
and you should offer those three operations (assuming transpose is a property of vector):
vector operator*( vector const& v, matrix const& m );
vector operator*( matrix const& m, vector const& v );
matrix operator*( matrix const& m1, matrix const& m2 );
matrix operator*( vector const& v1, vector const& v2 ); // possibly 1x1 matrix, you cannot overload changing only return value
All as free functions if possible. Even if the above set is not symmetric, neither is the real world and your users will expect it.