如何为您自己的类型提供自由的开始/结束功能 [英] How to provide free begin/end functions for your own types
问题描述
在他最近的一次会谈中,Herb Sutter建议更喜欢自由 begin(container)
end(container)
函数模板 container.begin()
。我喜欢它,因为这些函数可以提供给所有不与begin()/ end()方法一起使用的可迭代类型。因为我的大部分领域类都有接口在领域语言谈,并不使用一般的名称,如begin / end,我现在可以提供一个可迭代的接口兼容STL容器和范围基地for循环,而不会搞乱主类接口。
我想知道什么是为我自己的类型提供begin / end函数的最佳方式。我的第一个想法是用和 swap
相同的方式做,并将该函数写在我的类型所在的同一个命名空间中。
In one of his latest talks, Herb Sutter recommended to prefer the free begin(container)
end(container)
functions templates over container.begin()
. I like it, because these function can be provided for all iterable types that don't come with begin()/end() methods. Since most of my domain classes have interfaces that talk in the domain language and don't use general names like begin/end, I can now provide an iterable interface compatible to STL containers and range base for loops without messing up the main class interface.
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 I do with swap
and write the 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();
}
}
这里,还是应该在std命名空间?我认为另一种方式是在std命名空间中提供一个专门化(std不允许重载,对吗?)。
Is it ok to rely in ADL here, or should they be in std namespace? I think another way is to provide a specialization in std namespace (overloading in std is not allowed, right?). What is the best way espacially regarding lookup for range based for loops?
推荐答案
我会让ADL做它的工作。虽然你允许在 std
命名空间中添加专门化,但是当你的命名空间中的一个简单的自由函数足够时,我没有强烈的理由这样做。
I would let ADL do its work. While you are allowed to add specializations in the std
namespace, there is no strong reason I can think of for doing so when a plain free function in your namespace suffices.
特别是对于循环的范围,标准状态是:
In particular for the range for loops, the standard states:
§6.5.4 / 1( begin-expr 和 end-expr 的定义):
- 否则,begin-expr和end-expr分别为
begin(__ range)
和end(__ range)
和结束都是用参数相关的查找(3.4.2)查找的。对于此名称查找,命名空间std是关联的命名空间。
- otherwise, begin-expr and end-expr are
begin(__range)
andend(__range)
, respectively, where begin and end are looked up with argument-dependent lookup (3.4.2). For the purposes of this name lookup, namespace std is an associated namespace.
这篇关于如何为您自己的类型提供自由的开始/结束功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!