如何为您自己的类型提供自由的开始/结束功能 [英] How to provide free begin/end functions for your own types

查看:97
本文介绍了如何为您自己的类型提供自由的开始/结束功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在他最近的一次会谈中,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) and end(__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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆