poorva
poorva

Reputation: 1766

Define operator ** in C++

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 ?

Upvotes: 9

Views: 4192

Answers (7)

user1233963
user1233963

Reputation: 1490

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

Upvotes: 5

jrd1
jrd1

Reputation: 10726

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;
}

Upvotes: 3

jrok
jrok

Reputation: 55395

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.

Upvotes: 5

Ivan
Ivan

Reputation: 2057

You can't overload operators for built-in types. I'd use operator ^ for such purpose for custom types.

Upvotes: 0

Drew Hall
Drew Hall

Reputation: 29055

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.

Upvotes: 0

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.

Upvotes: 11

You can't. You can only overload existing operators, and not for built in types.

Upvotes: 19

Related Questions