13

在对标准容器进行迭代时,您认为省略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) { /*...*/ }

是否有任何理由这样做或不这样做?

4

2 回答 2

17

如果您打算使用 ADL 来更改容器类型而不更改循环,请添加using std::begin; using std::end;. 这确保它可以std从其他具有beginend成员的命名空间中找到容器的函数,但在它们的命名空间中没有自由函数。

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
于 2012-06-28T10:28:59.670 回答
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可以是程序员定义的类型,比如在 namespace 中xyz,那么如果我编写std::begin而不是仅仅begin(在初始化部分),上面的函数模板将如何工作?

于 2012-06-28T10:30:19.827 回答