是否可以在结构体外部编写自动转换运算符?
具体情况如下: 我已经在系统 API 结构中定义了 CGPoint
和 CGSize
,并且我希望能够编写 my_point = my_size
。 我无法修改 CGPoint 结构,只能编写外部运算符。我可以编写二元运算符(+
、-
、...),但 operator=
必须在结构内部声明。那么还有其他解决办法吗?
The exact situation is next:
I have defined in system API structs CGPoint
and CGSize
, and I want to be able to write my_point = my_size
.
I can't modify CGPoint
struct, only can write external operator. I can write binary operators (+
, -
, ...) but operator=
must by declared inside struct. So is there any other solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
要使表达式
a = b;
编译,您需要在a
类型中拥有一个operator=
,它接受该类型的元素b
的类型,或可从b
隐式转换的类型。第一种情况被排除,因为
operator=
必须是该类的成员,并且由于您无法修改GLPoint
,因此您无法添加GLPoint& GLPoint::operator=( GLSize )
。第二种情况也存在同样的问题。从
GLSize
到GLPoint
的隐式转换可以作为GLPoint
中的隐式构造函数实现(已排除),或者作为成员运算符实现
,需要修改GLSize
中的 GLPoint()GLSize
。转换也不能作为免费功能添加。替代方案是使用非运算符语法,如添加一个自由函数
assign
(或copy
):GLPoint&分配(GLPoint&,GLSize const&)
。下一个问题是你为什么要这样做。如果
GLPoint
和GLSize
的设计者没有考虑到尺寸应该可以分配给点,那么为什么你觉得它们应该是可以分配的呢?一般来说,将类型分开是一个好主意,因为这将使编译器能够检测到您在代码中可能犯的错误。如果您允许从
GLSize
到GLPoint
的隐式转换,您可能会错误地输入如下内容:distance( point1, size2 )
,其中您的意思是>distance( point1, point2 )
,并且由于存在转换,编译器会很乐意进行转换并应用。然后您会看到奇怪的结果,并且您将花费相当多的调试时间来尝试确定逻辑错误的位置。除非该领域对每个运算符在该上下文中的含义有非常明确的定义,否则我将不惜一切代价避免运算符重载。 每个人阅读您的代码是否会立即明白
GLPoint(1,2) + GLSize(5)
代表什么,没有任何疑问或歧义?如果情况并非如此,如果人们会感到惊讶甚至怀疑,那么请避免运算符重载并使用命名函数:move_up( GLPoint&, GLSize )
(或任何 point+size 对您意味着什么)To make the expression
a = b;
compile you need to either have anoperator=
in the type ofa
that takes an element of the type ofb
, or a type implicitly convertible fromb
.The first case is ruled out, since
operator=
must be a member of the class, and since you cannot modifyGLPoint
then you cannot addGLPoint& GLPoint::operator=( GLSize )
.The second case suffers the same type of problems. An implicit conversion from
GLSize
toGLPoint
can be implemented as an implicit constructor inGLPoint
(ruled out), or as a memberoperator GLPoint()
inGLSize
, which requires modification ofGLSize
. Conversions cannot be added as free functions either.The alternatives are using non-operator syntax, as adding a free function
assign
(orcopy
):GLPoint& assign( GLPoint&, GLSize const & )
.The next question is why would you want to do so. If the designers of
GLPoint
andGLSize
did not consider that a size should be assignable to a point, then why do you feel that they should be assignable? In general it is a good idea to keep types separate, as that will enable the compiler to detect mistakes you might make in your code.If you allow implicit conversions from
GLSize
toGLPoint
, you might by mistake type something like:distance( point1, size2 )
where you meantdistance( point1, point2 )
, and because there is a conversion, the compiler will gladly convert and apply. Then you will see strange results, and you will spend quite a few nice debugging hours trying to determine where the logic is wrong.Unless the domain has a very clear definition of what each operator means in that context, I would avoid operator overloading at all costs. Will everyone reading your code immediately understand what
GLPoint(1,2) + GLSize(5)
represents without any doubt or ambiguity? If that is not the case, if people will be surprised or even doubt, then avoid operator overloading and use named functions:move_up( GLPoint&, GLSize )
(or whatever point+size means to you)如果您可以从 CGPoint 派生或包装 CGPoint 并在整个代码中使用新类,那么您可以提供您喜欢的任何运算符。新类可以有一个到
CGPoint
的转换运算符,以促进与现有函数的交互。If you can derive from or wrap CGPoint and use the new class instead throughout your code, then you can provide whatever operators you like. The new class can have a conversion operator to
CGPoint
facilitating interaction with existing functions.当您将
CGSize
分配给CGPoint
时,会发生什么?将其提取到某个运算符中,您就得到了它 - 例如,这有什么难的?这是一个示例:http://www.ideone.com/FZN20
When you assign a
CGSize
to aCGPoint
- what happens? Distil that into some operator and there you have it - for exampleWhat's so difficult about this? Here is an example: http://www.ideone.com/FZN20
其他答案似乎错过了明显的解决方案:添加一个函数将 CGPoint 转换为 CGSize。当然,这并不完全是您想要的(
size = point
),但由于您无法修改两个类中的任何一个,因此这是唯一的方法:Other answers seams to miss the obvious solution : add a function to convert CGPoint into CGSize. Off course, that is not exactly what you want (
size = point
), but since you can not modify either of two classes, this is the only way :