9

如何定义运算符**,使其可以执行 2 个数字的幂运算。例如2 ** 3。它的答案应该是 8。

或者间接有什么方法可以用运算符重载而不是#define宏来做到这一点?

4

7 回答 7

19

你不能。您只能重载现有的运算符,而不能重载内置类型。

于 2013-10-28T10:13:21.963 回答
10

你不能。您只能重载 C++ 中现有的运算符;您不能添加新的,或更改现有运算符的数量或关联性。甚至预处理器在这里也无能为力——它的标识符不能是符号。

于 2013-10-28T10:13:59.470 回答
5

就像提到的其他答案一样,这对于内置类型是不可能的,但是您可以让它适用于这样的自定义类型(最小代码示例):

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

活生生的例子

于 2013-10-28T11:33:11.010 回答
5

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.

于 2013-10-28T10:25:32.367 回答
3

正如其他人所指出的:这是不可能的。您可以重载另一个运算符,例如^,用于求幂,但是在一个简单的类型包装类/对象上。

但是,如果您喜欢冒险,另一种方法是创建一个微型 DSL,以支持此类运算符的动态计算。(一个著名的例子是 C++ 中的 LISP)

但是,考虑到所涉及的努力,它可能是也可能不是您的一杯茶。然而,值得知道这种可能性是存在的。

更新:

运算符重载通过重载已经存在的运算符来工作。为什么?因为如果您可以定义自己的,您还必须定义这些运算符的优先级,这些运算符很容易通过抽象出它们的原始目的而让位于滥用运算符 - 这增加了阅读代码时的难度。(至少这是已经提出的论点)。

语义最接近的运算符**是插入符号运算符。这种运算符的简单和说明性实现是:

#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;
}
于 2013-10-28T10:18:53.323 回答
0

您不能为内置类型重载运算符。我会operator ^为此目的使用自定义类型。

于 2013-10-28T10:15:07.690 回答
0

不幸的是,可以在 C++ 中重载的运算符集是固定的,不包括 ** 运算符。您可能会考虑operator^()改用,但事实证明 ^ 用作幂运算符的优先级错误。

简而言之,不幸的是,您对此无能为力。

于 2013-10-28T10:16:03.760 回答