问题
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?
回答1:
To make the expression a = b;
compile you need to either have an operator=
in the type of a
that takes an element of the type of b
, or a type implicitly convertible from b
.
The first case is ruled out, since operator=
must be a member of the class, and since you cannot modify GLPoint
then you cannot add GLPoint& GLPoint::operator=( GLSize )
.
The second case suffers the same type of problems. An implicit conversion from GLSize
to GLPoint
can be implemented as an implicit constructor in GLPoint
(ruled out), or as a member operator GLPoint()
in GLSize
, which requires modification of GLSize
. Conversions cannot be added as free functions either.
The alternatives are using non-operator syntax, as adding a free function assign
(or copy
): GLPoint& assign( GLPoint&, GLSize const & )
.
The next question is why would you want to do so. If the designers of GLPoint
and GLSize
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
to GLPoint
, you might by mistake type something like: distance( point1, size2 )
where you meant distance( 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)
回答2:
When you assign a CGSize
to a CGPoint
- what happens? Distil that into some operator and there you have it - for example
CGPoint& operator|=(CGPoint& cPoint, CGSize const& cSize)
{
// now set attributes of cPoint that you can extract from cSize
return cPoint;
}
What's so difficult about this? Here is an example: http://www.ideone.com/FZN20
回答3:
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.
回答4:
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 :
CGSize ToSize( const CGPoint &pt )
{
CGSize res = ...
// do the conversion
return res;
}
来源:https://stackoverflow.com/questions/6120841/is-it-possible-to-write-auto-cast-operator-outside-a-struct