问题描述
在他最近的一次会谈中,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:
- 否则,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.
这篇关于如何为您自己的类型提供自由的开始/结束功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!