4

In the documentation for boost.geometry it states

Note: prefer using x = bg::get:<0>(point1);
(as opposed to x = point1.get<0>();)

I have seen this elsewhere in the boost docs. My question is why? Is this a best-practices thing, a performance thing or some quirk? Is it a general rule or specific to this library?

3
  • 1
    For an existing point type (provided by someone else), you can implement a free get function that acts on it, but you can't add a get member function, so it is more generic. Commented Jan 21, 2014 at 12:22
  • @MarcGlisse, but wouldn't an outside point type (if it is derived from the base class) necessarily have a get anyway? Is this the only reason? Commented Jan 21, 2014 at 12:30
  • 2
    If point1 has a dependant type then you also don't need to write point1.template get<0>(). Commented Jan 21, 2014 at 12:30

1 Answer 1

14

It's not boost per se, but modern C++ API design.

  • By not requiring member functions, you can adapt your own classes and even third party library types to work with the boost Api of your choice. (This way you can e.g. make types from a third party library serializable to a Boost Serialization archive).

  • Also, by making the functions free functions, there is an improved decoupling of dependencies. E.g.: fusion/tuple.hpp doesn't need to depend on anything IO related, because the streaming operations are free functions, and hence can be declared (and defined) in a separate header: fusion/tuple_io.hpp.

  • It also helps encapsulation because by default the free functions aren't friends of the host class (and as such are unable to access private members).

  • free functions can "Do The Right Thing" based on ADL:

    using std::swap; swap(a, b); // will lookup `swap` in the namespaces that declare the parameter types 

    (several other namespaces are also used for lookup)

  • Finally, free functions can generically service a group of types, that need not be OO-related (inheritance related). In this way, free functions encourage avoiding duplication of code.

Edit Addressing the question of why you should prefer the non-member syntax, if both exist:

  • it works for types that don't have the member function
  • it doesn't require .template disambiguation in template code (as pointed out by @Simple)
  • Again: it's not boost specific.

    • c++03 has had std::swap() as a free function
    • c++11 introduces std::begin() and std::end() as free functions
    • std::hash<>, std::less<>, std::greater<>, std::equal_to<> similarly provide customization points that are not intrusive (but aren't functions of course)
Sign up to request clarification or add additional context in comments.

4 Comments

Off topic: out of interest, what's the use case for customizing std::less in preference to free operator<? You're right that it provides a customization point, but I think it's a pretty obscure one: you want your type to be comparable by algorithms and containers, but not by code that normal human beings write ;-) Is there some annoying consequence of partial specialization that means sometimes you have to put up with that?
@SteveJessop The most annoying thing with free functions I can think of would be the Pitfalls of ADL, i.e. that ADL can also easily DoTheWrongThing(TM). There's no way to "control" ADL (other than to prohibit it). Yes, library writers can (and should) be defensive about this (by using ADL barrier namespaces). But function objects have the distinct property that they don't participate in ADL by definition. (I know Eric Niebler has advocated this and used it as a principle in designing Proto0x).
I don't know whether this was the design principle for the standard library. Perhaps they just wanted the ability to e.g. instantiate container types with a concrete comparator type, as opposed to having to initialize some kind of "generic function type" with a specific instance object on construction always.
yes, I see reasons for std::less to exist. It's just using it as the customization point for a user-defined type that I'm puzzled by: it's allowed but I don't think I've ever done it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.