How to provide free start and end functions for your own types

In a recent interview, Herb Sutter recommended choosing free begin(container) end(container) function templates over container.begin() . I like it because this function can be provided for all repeating types that don't come with begin () / end () methods. Since most of my domain classes have interfaces that speak the domain language and do not use common names such as start / end, now I can provide an iterative interface compatible with STL containers and range bases for loops without spoiling the interface of the main class. I am wondering what is the best way to provide begin / end functions for my own types. My first thought was to do it the same way as with swap , and write a function in the same namespace where my type lives.

 namespace My { class Book { public: typedef std::vector<Page>::const_iterator PageIterator; PageIterator FirstPage() const { return begin(pages_); } PageIterator LastPage() const { return end(pages_); } private: std::vector<Page> pages_; }; Book::PageIterator begin(const Book& b) { return b.FirstPage(); } Book::PageIterator end(const Book& b) { return b.LastPage(); } } 

Can you rely on ADL here, or should they be in the std namespace? I think the other way is to provide specialization in the std namespace (overloading in std is not allowed, right?). What is the best way espacially regarding loop-based range searching?

+8
c ++ c ++ 11
source share
2 answers

I would let ADL do my job. Although you are allowed to add specializations to the std , I cannot believe that a simple free function in your namespace is sufficient for this.

In particular, for the range for cycles, the standard states are:

Β§6.5.4 / 1 (definition of begin-expr and end-expr):

  • otherwise, begin-expr and end-expr are equal to begin(__range) and end(__range) , respectively, where the beginning and end are scanned with a search argument dependent (3.4.2). For the purpose of finding this name, the std namespace is an associated namespace.
+8
source share

This is normal and it is recommended that you rely on ADL. The begin and end functions are part of your type interface (whether they are stand-alone functions or not), and they must be in the same namespace as your type.

+4
source share

All Articles