【发布时间】:2016-04-01 12:42:49
【问题描述】:
在 C++ 中很容易引入新的中缀运算符
// 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;
}
不幸的是,这个幂运算符有错误的优先级和关联性。所以我的问题是:如何解决这个问题?我希望我的 <pow> 具有比 * 更高的优先级并关联到右侧,就像在数学符号中一样。
编辑 可以通过使用不同的括号来改变优先级,例如|op|、/op/、*op* 甚至,如果有人愿意的话,<<--op-->>,但这样一来就不能高于内置运算符的最高优先级。但如今,C++ 在模板元编程和类型推导方面如此强大,根本就应该有其他方法来达到预期的效果。
此外,如果我可以使用pow 而不是pwr,那就太好了。不幸的是,在某些实现中,#include <cmath> 将pow 带入了全局命名空间,因此会有冲突。我们可以重载operator not 以便声明表单
not using std::pow;
从全局命名空间中删除了std::pow?
【问题讨论】:
-
“简单”......哈哈。 (就像,说真的,我希望这只是为了研究目的)
-
您不能“发明”新的运算符,您只需使用现有的运算符来模拟与运算符相似但不是实际运算符的东西。这就是运算符优先级不起作用的原因。为了回答你的问题,没有办法解决这个问题。
-
这有点类似于“运行到”运算符的想法:
while(i ----> 0)。非常方便! -
哈哈,Bjarne Stroustrup 的提议简直是个巨魔:D
标签: c++ c++14 user-defined infix-operator