作为先前的说明:这不是我想要达到的目标;更多 - 这是一个与它是否真的有关的问题。
N.B。我理解(并且已经使用过)C ++中的运算符重写。例如:
std::ostream& operator<<(std::ostream& os, const T& obj){ return os; }
是否可以定义自定义ASCII字符作为运算符?
例如,从简单的意义上讲:使用严重重音(`)作为std :: pow的'别名'。
因此,以下陈述将是有效/可实现的:
std::cout << 2`3 << std::endl;
>> 8
答案 0 :(得分:70)
您不能引入语法中不存在的字符,例如您提到的反引号。但是有一个"named operator" trick,您可以使用它来引入“命名运算符”来实现以下语法:
std::cout << (2 <Pow> 3) << std::endl;
这个技巧依赖于为自定义类型重载<
和>
,如下所示:
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;
}
请注意,您不能影响这些命名运算符的优先级:它们具有与<
,<=
,>
和>=
相同的优先级。如果您需要不同的优先级,则必须使用不同的分隔符(可能不太可读)。
<强>声明强>
上面的技巧是“聪明”的代码,它几乎是滥用C ++语法。我把这个问题假设为一个假设的“可能的东西”,并回答了一个同样假设的“这就是”。我会不建议在实践中使用它来解决诸如替换std::pow
或提供“新颖”语法这样的微不足道的问题。上面提到的运算符优先警告是一个原因;对结构的一般不熟悉是另一种。代码质量是以代码生成的WTF数量来衡量的(越少越好),这个技巧会产生一大堆(以及那些大的)。
它仍有其用途:用于创建特定于域的语言。编程中存在将DSL嵌入到C ++代码中的情况;在这种情况下(在这种情况下仅)我会考虑使用它。
答案 1 :(得分:10)
不,那是不可能的。即使在预处理器级别,您也受到形成有效预处理器标记和宏名称的字符的限制,然后语言语法修复了该语言中的运算符集。