C++ – Member vs. free-standing functions with respect to interface uniformity

c

Item 23 of Effective C++ (3rd edition) by Scott Meyers is titled: "Prefer non-member non-friend functions to member functions". The reason Scott suggests is the increase of encapsulation. So, only the functions that need to access the private members are made member functions, the other functions are made free-standing.

Now, the user does not care about my considerations. All he wants is a clean uniform interface that is as simple to learn as possible. Having some functions as members and some as free-standing seems to break this uniformity. Furthermore, the choice of which function is member and which is free-standing may seem random to the user, who is unaware of the implementation details (i.e. the private members) of my class.

One answer even cites a language proposal related to this issue.

My question is: is it a good idea to always provide a free-standing wrapper function for each member function in order to present the user with a uniform interface consisting of free-standing functions only?

Best Answer

To directly answer the question you asked, I'd say the short answer is no: it's not necessarily worthwhile writing a wrapper for every member function, just to give a uniform interface.

That said, it can be worthwhile to do so if you have something that corresponds closely to a concept, that's defined entirely in terms of free functions, and by providing free-function wrappers, your class can model that concept. In this case, having those wrappers lets you use objects of that class with some set of templates that wouldn't otherwise work with them. The question at that point is whether those templates are likely to be useful with objects of this particular class. Even if the class happens to support the syntax necessary to model the concept, the operation(s) provided by those templates may not be useful with it--in which case, it's obviously pretty pointless.

At least in my view, providing wrappers so x.f(y) can be called like f(x,y), just so the programmer doesn't need to pay attention to whether f is a free function or a member function is generally misplaced. Yes, in a completely ideal world where time wasn't constrained at all, it might be worth considering. Likewise, in a few cases a class might be used so widely and heavily that it's worth considering putting in the extra time to write the wrapper in the hope of its paying off in the long run by making everybody else's lives easier.

Unfortunately, I don't think either of these applies very often. Most of us have way too large of a backlog of problems that really need fixing to give it serious consideration, at least until we have solid, objective evidence that the investment will pay off, and fairly soon at that. Doing it just to fulfill a principle without a fairly solid assurance of real benefits would be difficult to justify (at best).