在 C++ 中重载 **

Overloading ** in C++

在 Python 中,我们有很好的简单语法来获取任意 int/float 的幂。即,对于非Python程序员,我们可以有如下声明:

y = 2 ** 3 
print y

这会将 8 打印到控制台,并且语法很好,因为有一个内置的 "power" 运算符。是否可以在 C++ 中将“**”重载为单个运算符?具体来说,我想完成这样的事情:

int a = 2;
int b = 3;
cout << (a**b) << endl;

或者,如果这不可能,像这样:

MyInt a = new MyInt(2); // Wrapper class around ints to play nicely with **
MyInt b = new MyInt(3);
cout << (a**b) << end; // Assume ostream overridden for MyInt

这些也应该打印 8 到控制台。我知道覆盖“^”运算符来做同样的事情会容易得多,但我最感兴趣的是看看我是否可以重载“**”。运算符“*”(对于 MyInt class 的情况,如果它是一个成员函数)是否必须查看参数是否是另一个“*”,因为我不知道如何指定“ **”作为单个操作员?甚至可以将运算符作为参数传递吗?

Additional/bonus尽可能规定(好像我还没说够):没有宏!!!

简短回答: 不。在 C++ 中无法 "overload" 任意 character/token 序列。

更长的答案: a**b 等同于 a * (*b),所以你 可以 重载二进制 * (即乘法)和一元 * (即取消引用)以某种粗略的方式。但这对阅读您的代码的任何人来说都是 opaque/unexpected,并且将来 debug/maintain 会很痛苦。

只需编写一个名为 pow()!

的函数

你的意思是这样的?

#include <iostream>
#include <cmath>

struct MyInt {
    int val;
    struct MyProxy { int val; };

    MyProxy operator *() const{ return MyProxy{val}; }
    MyInt operator * (const MyProxy& b) { return MyInt{ static_cast<int>(std::pow(val, b.val)) }; }

};

std::ostream& operator << (std::ostream& o, const MyInt& m) { return o << m.val; }

int main(){
    MyInt a{5}, b{3};
    std::cout << a**b << std::endl;
}

现场观看http://coliru.stacked-crooked.com/a/ab56b9cd6e422e12

解释:

  1. 将一元 * 运算符重载到 return 代理对象
  2. 重载二进制 * 运算符以使用代理...简单 :-)
  3. 我使用代理 class 来避免细微的错误..

C++ 很有趣...我想相信您这样做是为了好玩 而不是在生产中 ... 因为它在生产中是一个非常糟糕的主意,只需调用 std::pow