C++ 用户定义的中缀运算符
在C语言中引入新的中缀运算符很容易++C++ 用户定义的中缀运算符,c++,c++14,user-defined,infix-operator,C++,C++14,User Defined,Infix Operator,在C语言中引入新的中缀运算符很容易++ // User-defined infix operator framework template <typename LeftOperand, typename Operation> struct LeftHelper { const LeftOperand& leftOperand; const Operation& operation; LeftHelper(const LeftOperand&a
// User-defined infix operator framework
template <typename LeftOperand, typename Operation>
struct LeftHelper
{
const LeftOperand& leftOperand;
const Operation& operation;
LeftHelper(const LeftOperand& leftOperand,
const Operation& operation)
: leftOperand(leftOperand), operation(operation) {}
};
template <typename LeftOperand, typename Operation >
auto operator < (const LeftOperand& leftOperand,
Operation& operation)
{
return LeftHelper<LeftOperand, Operation>(leftOperand, operation);
}
template <typename LeftOperand, typename Operation, typename RightOperand>
auto operator > (LeftHelper<LeftOperand, Operation> leftHelper,
const RightOperand& rightOperand)
{
return leftHelper.operation(leftHelper.leftOperand, rightOperand);
}
// Defining a new operator
#include <cmath>
static auto pwr = [](const auto& operand1, const auto& operand2) { return std::pow(operand1, operand2); };
// using it
#include <iostream>
int main()
{
std::cout << (2 <pwr> 16) << std::endl;
return 0;
}
是否从全局命名空间中删除了std::pow
进一步阅读:。最小惊喜原则很重要,关键是
a*b*power*c*d
评估a*(b^c)*d
。幸运的是,有一个简单的解决方案
为确保*power*
的优先级高于乘法,必须使用类似的命名运算符技术进行乘法
然后,您不再直接计算*power*
和*times*
的结果,而是构建一个表达式树。计算此表达式树时,可以应用任意优先级规则
我们可以对每个内置运算符执行此操作,这为我们提供了一种易于阅读的语法,允许对运算符优先级进行编译时元编程:
auto z =equals= bracket<
a *plus* b *times* c *power* bracket<
a *plus* b
>bracket *power* x *times* y
>bracket;
使用这种技术,所有运算符都有可读的名称,使其含义清晰明了,并且所有操作都以中缀完成,而不是混合使用中缀和前缀表示法
类似的解决方案可以确保
pow
可用,您可以自己重新实现
。这避免了重载非语言构造上的运算符,这会导致AST语法单子解耦和/或违反标准。也许可以试试哈斯克尔?“简单”。。。。。。。。。。哈哈。(比如,说真的,我希望这只是为了研究目的)你不能“发明”新的操作符,你只需要使用现有的操作符来模拟与操作符类似但不是实际操作符的东西。这就是运算符优先级不起作用的原因。为了回答您的问题,没有办法解决这个问题。这与“runs to”操作符有点类似:while(i-->0)
。非常方便!哈哈,比亚恩·斯特劳斯特鲁普的建议简直是一个巨魔:这是一个很好的主意。如果总是使用括号//括号
对于顶级括号,甚至可以保留标准的乘法符号*!至于哈斯克尔。。。我不知道,也许让斯诺曼?@n.m.我不知道,括号/
看起来很混乱。我们可以使用bra
ket
,这符合量子力学中的优先使用。如果使用传统的单符号操作符,如*
,您需要具有最高优先级的括号,因此bra<>ket
,尽管它们很吸引人,但不会起作用。一对bra//ket
可能是下一个最好的选择。我认为遗留的原始*
只会让程序员感到困惑;想象一下,如果有人有一个叫做cross的变量!为了支持那些不想跟上潮流的用户而竭尽全力是不值得的。
auto z =equals= bracket<
a *plus* b *times* c *power* bracket<
a *plus* b
>bracket *power* x *times* y
>bracket;
int z = (a + b* pow(c,pow(x,a+b))*y);