是否可以使用任意字符作为运算符?

Alf*_*mer 26 c++ operators

作为先前的注释:这不是我想要实现的东西; 更多 - 如果它确实可能的问题.

NB我理解(并且已经使用过)C++中的运算符重写.例如:

std::ostream& operator<<(std::ostream& os, const T& obj){ return os; }
Run Code Online (Sandbox Code Playgroud)

是否可以定义自定义ASCII字符作为运算符?

例如,从简单的意义上讲:使用重音符(`)作为std :: pow的'别名'.

因此,以下声明将是有效/可实现的:

std::cout << 2`3 << std::endl;

>> 8
Run Code Online (Sandbox Code Playgroud)

Rei*_*ica 70

您不能引入语法中不存在的字符,例如您提到的反引号.但是有一个"命名运算符"技巧,您可以使用它来引入"命名运算符"以实现以下语法:

std::cout << (2 <Pow> 3) << std::endl;
Run Code Online (Sandbox Code Playgroud)

这个技巧依赖于重载<>自定义类型,如下所示:

const struct PowOperator {} Pow;

struct PowInvoker
{
  int lhs;
};

PowInvoker operator< (int lhs, PowOperator)
{
  return {lhs};
}

int operator> (PowInvoker lhs, int rhs)
{
  return std::pow(lhs.lhs, rhs);
}

int main()
{
  std::cout << (2 <Pow> 3) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

[实例]

请注意,您可以在不影响这些命名符的优先级:它们将具有相同的优先级<,<=,>,和>=.如果您需要不同的优先级,则必须使用不同的分隔符(可能不太可读).


放弃

上面的技巧是"聪明"的代码,它几乎是滥用C++语法.我把这个问题假设为一个假设的"可能的东西",并回答了一个同样假设的"这就是".我建议在实践中使用它来解决诸如替换std::pow或提供"新颖"语法之类的微不足道的问题.上面提到的运算符优先警告是一个原因; 对结构的一般不熟悉是另一种.代码质量是以代码生成的WTF数量来衡量的(越少越好),并且这个技巧会产生一大堆(和那些大的).

它仍有其用途:用于创建特定于域的语言.编程中存在将DSL嵌入到C++代码中的情况; 在这种情况下(并且在这种情况下)我会考虑使用它.

  • 我会残忍地毁掉那些在"真实"代码中使用过它的人,但+1会对一个假想问题的一个有趣答案. (34认同)
  • @ApproachingDarknessFish替换`std :: pow`不是这个用途,但它可以为某些情况提供可行的DSL. (4认同)
  • @Angew有趣的概念; 感谢您对'named-operator'技巧的链接.我以前从未见过这样做过. (2认同)

Ker*_* SB 10

不,那是不可能的.即使在预处理器级别,您也会受到形成有效预处理器标记和宏名称的字符的限制,然后语言语法会修复该语言中的运算符集.