如何定义运算符**
,使其能够对两个数字进行指数运算。例如2 ** 3
。它应该给出8作为答案。
或者间接地说,我是否可以通过运算符重载来实现这一点,而不是使用#define
宏?
如何定义运算符**
,使其能够对两个数字进行指数运算。例如2 ** 3
。它应该给出8作为答案。
或者间接地说,我是否可以通过运算符重载来实现这一点,而不是使用#define
宏?
你不能这样做。你只能重载现有的运算符,而不能针对内置类型进行操作。
supertypedef int potatoes;
和一个自由运算符:potatoes operator *(const potatoe a, const potatoe b) { return std::pow(a, b); }
但现在当我写下来时,它看起来甚至对我自己都很愚蠢。 - PaperBirdMaster你不能。在C++中,只能重载现有的运算符,无法添加新的运算符或更改现有运算符的参数个数或结合性。即使是预处理器在这里也无能为力——它的标识符不能成为符号。
命名运算符惯用法
来定义新的操作符。参见:https://github.com/klmr/named-operator - sehe**
并且想让你的代码更加混淆:#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
函数。#define $$ *power_of*
,这样就可以使用 2 $$ 3
。此外,我会使用从右到左结合的运算符,例如 *=
,因此 4 $$ 3 $$ 2
的结果将是 262144
。演示 - Evgeny Panasyuk正如其他答案所指出的,对于内置类型来说这是不可能的但是你可以按照以下方式使自定义类型实现此功能(最小代码示例):
#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;
}
2 ** 1
这样的计算。你可以使用运算符重载,但是由于C++本身不支持像**
这样的运算符重载(注意,我说的是本地支持),那么这个练习显然就需要利用C++的不同理解和应用来解决这个问题。提示是它可能是一个在编译时可以用宏完成的解析问题,或者是在运行时可以用类、对象和函数完成的解析问题。 - jrd1operator ^
来实现这样的目的。不幸的是,在C++中可以重载的运算符集是固定的,不包括**运算符。您可能会考虑使用operator^()
代替,但事实证明^的优先级不正确,无法用作指数运算符。
简而言之,对此您无能为力,很遗憾。