В одном из своих последних выступлений Херб Саттер рекомендовал использовать бесплатные begin(container)
end(container)
шаблоны функций вместо container.begin()
. Мне это нравится, потому что эти функции могут быть предоставлены для всех итерируемых типов, которые не поставляются с методами begin () / end (). Поскольку большинство моих классов доменов имеют интерфейсы, которые говорят на языке домена и не используют общие имена, такие как begin / end, теперь я могу предоставить итеративный интерфейс, совместимый с контейнерами STL и основой диапазона для циклов, не путая интерфейс основного класса.
Мне интересно, как лучше всего обеспечить начало / конец функций для моих собственных типов. Моей первой мыслью было сделать то же самое, что я сделал с swap
и написать функцию в том же пространстве имен, где живет мой тип.
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();
}
}
Можно ли полагаться на ADL здесь или они должны быть в пространстве имен std? Я думаю, что другой способ - обеспечить специализацию в пространстве имен std (перегрузка в std не разрешена, верно?). Каков наилучший способ поиска диапазона для циклов?