The basic argument here is that cohesion and reusability is improved if you don't create member functions that don't require access to private data. i.e. can be implemented efficiently using only member functions.
Personally, I think C++ took that philosophy a bit too far, but I also think most libraries take it a bit too far the other way.
For example, consider finding the complex number with the largest magnitude from a list of complex numbers. You can't make this a member function of Complex
because it operates on a list. You can make max
a member function of List
, but it doesn't know how to compare complex numbers. So you have some sort of Ordering
interface or type class. You can't just make Complex
implement this interface, because of the ISP, but also because you might want to also be able to order a Complex
by real component or imaginary component sometimes instead of magnitude.
So where do you put all the Ordering
implementations for Complex
? Now you have a place that's separate from the Complex
class, but still "belongs" to the Complex
class.
Most OO programmers don't find that separation strange, because they were syntactically forced into it. But they don't think twice about clumping things together when they aren't forced to separate them, even when there might be a different, more cohesive grouping.
auto znorm = norm(z)
? The result might surprise you.std::
prefix.