是否可以在结构外部编写自动转换运算符

Is it possible to write auto-cast operator outside a struct?

本文关键字:转换 运算符 外部 结构 是否      更新时间:2023-10-16

具体情况如下:我已经在系统API中定义了结构CGPointCGSize,我希望能够编写my_point = my_size。我不能修改CGPoint结构,只能写外部运算符。我可以编写二进制运算符(+-…),但必须在结构内部声明operator=。那么,还有其他解决方案吗?

要编译表达式a = b;,您需要具有a类型的operator=,该CCD_9接受b类型的元素,或者具有从b隐式转换的类型。

排除了第一种情况,因为operator=必须是类的成员,并且由于不能修改GLPoint,所以不能添加GLPoint& GLPoint::operator=( GLSize )

第二个案例也存在同样的问题。从GLSizeGLPoint的隐式转换可以在GLPoint中实现为隐式构造函数(排除),也可以在CCD20中实现为成员operator GLPoint(),这需要修改GLSize。转换也不能作为自由函数添加。

替代方案是使用非运算符语法,如添加自由函数assign(或copy):GLPoint& assign( GLPoint&, GLSize const & )

下一个问题是你为什么要这样做。如果GLPointGLSize的设计者没有考虑到一个大小应该可以分配给一个点,那么你为什么觉得它们应该是可以分配的呢?一般来说,将类型分开是个好主意,因为这将使编译器能够检测您在代码中可能犯的错误。

如果您允许从GLSizeGLPoint的隐式转换,您可能会错误地键入以下内容:distance( point1, size2 ),您的意思是distance( point1, point2 ),因为有转换,编译器会很乐意转换并应用。然后,您将看到奇怪的结果,并且您将花费相当多的nice调试时间来尝试确定逻辑错误的位置。

除非域对每个运算符在该上下文中的含义有一个非常明确的定义,否则我将不惜一切代价避免运算符过载。阅读您的代码的每个都会立即理解GLPoint(1,2) + GLSize(5)所代表的内容吗?如果不是这样,如果人们会感到惊讶甚至怀疑,那么请避免运算符重载,并使用命名函数:move_up( GLPoint&, GLSize )(或任何点+大小对您来说意味着什么)

当您将CGSize分配给CGPoint时,会发生什么?把它分散到一些运营商那里,你就有了它——例如

CGPoint& operator|=(CGPoint& cPoint, CGSize const& cSize)
{
  // now set attributes of cPoint that you can extract from cSize
  return cPoint;
}

这有什么困难?以下是一个示例:http://www.ideone.com/FZN20

如果您可以从CGPoint派生或包装CGPoint,并在整个代码中使用新类,那么您可以提供任何您喜欢的运算符。新类可以具有到CGPoint的转换运算符,以便于与现有函数进行交互。

其他答案遗漏了显而易见的解决方案:添加一个函数将CGPoint转换为CGSize。当然,这并不是你想要的(size = point),但由于你不能修改两个类中的任何一个,这是唯一的方法:

CGSize ToSize( const CGPoint &pt )
{
  CGSize res = ...
  // do the conversion
  return res;
}