简体   繁体   中英

Why can overloaded compound assignment operators be non-member functions?

I've just discovered recently that compound assignment operators (such as operator+= or operator-= ) can be overloaded outside class scope.

Consider:

class X { }; // A third party class

// The following function is legal:
X& operator+=(X& lhs, const X& rhs) {
    // ...
}

Obviously, the non-member function can't touch the private interface of X , so there's no encapsulation concern here. But it does make it seem as if it's part of X 's own interface, which it clearly isn't.

It seems to me this can lead to some serious code abuse and confusing behavior. Imagine someone thought it would be nice to use it for some "clever hacks" with standard contains such as std::vector or std::map .

This is especially peculiar since other operators such as operator[] and operator-> can't be non-member functions for what I thought was this very reason.

So why is it allowed?

So why is it allowed?

You are asking us to read the mind of Stroustrop. Not possible.
But a general principle of C++ is not to limit developers (we don't provide a neutered set of tools that are safe to play with. We provide the full set of razor saws and spinning flails).

It seems to me this can lead to some serious code abuse and confusing behavior. Imagine someone thought it would be nice to use it for some "clever hacks" with standard contains such as std::vector or std::map.

Yes it can.
When you abuse operator overloading it can lead to some dangerous and deadly things. Best not to do it (especially for other peoples or standard classes).

But it can provide some potentially useful situation (when you are careful). This is particularly useful when you are building a numeric "type" class as it helps with auto conversions which make the code more natural to read.

Consider if library A defines an object (let's say a Matrix object). Library B extends library A with some similar object (let's say Vectors).

Library B wants to define operators which link matrices to vectors (eg multiply). But if defining these operator overloads had to be done within the original object, the writers would be stuck, and users would be left in the strange situation where they can do vector * matrix, but not matrix * vector.

To look specifically at += and -= as you mention, consider a 1-by-n matrix, which is essentially a vector. We now want to be able to perform matrix += vector.

Allowing them to be defined externally avoids this problem.

It seems to me this can lead to some serious code abuse and confusing behavior

Quite right. But don't forget this is a language which has a built-in preprocessor. If other developers want to confuse you, they already have much more powerful tools available.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM