在C++中定义运算符 **

Define operator ** in C++

本文关键字:运算符 定义 C++      更新时间:2023-10-16

如何定义运算符**,以便它可以执行 2 个数字的幂. 例如2 ** 3 .它应该给出答案为 8。

或者间接有没有办法用运算符重载而不是#define宏来做到这一点?

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

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

如果你愿意做出妥协的话。 **并想混淆您的代码:

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

否则,只需使用 std::pow .

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

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

现场示例

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

但是,如果您喜欢冒险,另一种方法是创建一个微型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;
}

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

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

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