5 Comments

  1. Markus Palcer

    As you were talking about which overloads of addition are good and which I bad I wondered:

    – You were talking about the addition of two players, which clearly raises the question what the semantic should be, but what if you define the addition as follows: Player operator+(Player const & p; Score_t const & s);
    Would that be okay since the signature shows that you add a specific score to the player.
    I personally would see that as okay because the signature (using the type Score_t) shows that you are adding a score to the player.

    – You were talking about the addition of two containers not being okay which also is reasonable. How about adding a single element not with an add but the operator+?
    Here I’d say that isn’t okay either especially if the element type already has the operator + defined (being a numerical type for example).
    Because I wouldn’t know if this operator+ for the container should be a “map(+)” (when thinking in functional programming terms) or an “append”.

    Reply
    1. Arne Mertz

      Hi Markus, thanks for your thoughts!
      With respect to the player-score addition I see a few problems:
      The first is the assignment of players. You usually don’t want to write `playerX = playerY` because of unclear semantics (would that mean you end up with two players that have the same name, ID, whatever?) – so assignment between players should be made inaccessible. If that is the case, your proposed operator would not be of much use because you can not write `playerX = playerX + someScore`. The only viable alternative would be to overload operator+= instead to write `palyerX += someScore`. However, having operator+= but not operator+ feels a bit awkward, and I don’t see much of a benefit compared to a simple `addScore` method. Then there is the `Score_t` type. If you want to add a fixed score, then you would either have to write `playerX += Score_t(22)` if there is no implicit conversion, or `playerX += 22` if the conversion exists. The latter case is all but clear for a reader – does that add 22 to a score, health points or gold or some other quantity? The former is not less verbose than `playerX.addScore(22)`, so again I see no benefit there.

      For the container add I agree that such an operator would not be clear. However, in Boost.Assign there are operators defined to add elements to containers. They are interpreted as insertions, not as additions to each element.

      When it comes to operator overloading, there is a grey zone between what makes perfect sense and what may be unclear. For my part, I prefer to stay well away from anything that might be unclear. That leaves me with two kinds of concepts where operator overloading is appropriate: Well known concepts such as numbers, where there is no doubt what the operators mean, and the complete opposite: completely unknown terrain like embedded DSLs, where the user has to learn every aspect from scratch anyways, so the operators can not be misinterpreted at all. For an example of the latter, see this post about embedded DSLs.

      Reply



Leave a Reply

Your email address will not be published. Required fields are marked *