依赖于ADL for std :: begin()和std :: end()?

时间:2012-06-28 10:21:06

标签: c++

在迭代标准容器时,您认为省略std::前缀并依赖ADL查找定义是个好主意吗?例如:

std::vector<int> vec = get_vec();
// range-based for loop would be preferred here, but just for the sake of example
for (auto it = begin(vec), end = end(vec); it != end; ++it) { /*...*/ }

有没有理由这样做?

2 个答案:

答案 0 :(得分:14)

如果您要使用ADL在不更改循环的情况下更改容器类型,请添加using std::begin; using std::end;。这确保它从具有stdbegin成员的其他名称空间中找到容器的end函数,但在其名称空间中没有自由函数。

namespace my {
    template <typename T>
    struct container {
        // ... stuff
        iterator begin();
        iterator end();
    };
    // no begin/end free functions
}


my::container<int> vec = get_vec();
using std::begin;
using std::end;
for (auto it = begin(vec), end = end(vec); it != end; ++it) { /*...*/ }
// defaults to std::begin which defaults to .begin() member function

答案 1 :(得分:8)

  

你认为省略std ::前缀并依靠ADL查找定义是个好主意吗?

我认为这是个好主意。在这样的模板中有必要:

template<typename Container>
void do_work(Container const & c)
{ 
  using std::begin;  //enable ADL
  using std::end;    //enable ADL 

  //now let compiler search the correct begin/end in the initialization part
  for(auto it = begin(c), itend = end(c); it != itend ; ++it)
  {
       //do work
  } 
}

由于Container可以是程序员定义的类型,比如命名空间xyz,因此如果我写std::begin而不是{{1},上述函数模板将如何工作? (在初始化部分)?