在 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
解释:
- 将一元
*
运算符重载到 return 代理对象
- 重载二进制
*
运算符以使用代理...简单 :-)
- 我使用代理 class 来避免细微的错误..
C++ 很有趣...我想相信您这样做是为了好玩 而不是在生产中 ... 因为它在生产中是一个非常糟糕的主意,只需调用 std::pow
在 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
解释:
- 将一元
*
运算符重载到 return 代理对象 - 重载二进制
*
运算符以使用代理...简单 :-) - 我使用代理 class 来避免细微的错误..
C++ 很有趣...我想相信您这样做是为了好玩 而不是在生产中 ... 因为它在生产中是一个非常糟糕的主意,只需调用 std::pow