cppreference提及的运算符对称性是否指交换律?为何5.*vec3{}编译失败?
问题解答
1. 为什么5. * vec3{}无法编译?
你只实现了**左操作数为vec3、右操作数为double**的operator*重载,但C++的运算符重载是严格匹配参数顺序的。当你写5. * vec3{}时,编译器会寻找签名为operator*(double, const vec3&)的函数,而你并没有定义这个版本,因此编译报错。
解决方法很简单,补充一个反向的非成员重载即可,还能复用已有的实现(因为标量与向量相乘满足数学交换律):
auto operator* (double d, const vec3 &a) { return a * d; // 直接调用已有的vec3*double版本 }
2. 关于cppreference提到的“对称性”
这里的“对称性”确实和交换律相关,但更准确的描述是:让运算符支持不同类型的操作数在左右两侧都能被正确解析,只要这种调换在语义上是合理的。
比如复数和整数相加,不管是complex + int还是int + complex都应该能正常工作——这就是对称性的体现:不是强制运算符必须满足数学交换律,而是通过非成员函数的形式,方便我们为不同参数顺序的情况都提供重载,让代码的语法表现符合用户的直觉。
如果把二元运算符定义为成员函数,那么左操作数必须是类的实例,就无法直接支持int + complex这种左操作数为内置类型的情况;而非成员函数则没有这个限制,能轻松实现双向的运算符支持,这也是cppreference推荐用非成员函数实现二元运算符的核心原因。
内容的提问来源于stack exchange,提问作者Christopher Miller
相关产品推荐
相关产品推荐

