在C++ 11中迭代容器的推荐方法是什么?

Joh*_*ell 26 c++ algorithm stl c++11

在C++ 11中迭代容器的推荐方法是什么?

运用

container.begin() and container.end()
Run Code Online (Sandbox Code Playgroud)

要么

begin(container) and end(container)
Run Code Online (Sandbox Code Playgroud)

如果有的话,何时优先于另一个?

Bas*_*tch 37

我认为新的语法与范围基于循环

 for (auto item : container)
Run Code Online (Sandbox Code Playgroud)

可能是最喜欢的C++ 11.

正如其他人评论的那样,你有时想要auto&或   const auto&代替auto.

  • 我会把这些项目作为参考:`auto&item:container`,以避免不必要的副本. (11认同)
  • @Xeo:当然`const auto&`也很有帮助! (9认同)
  • @Johann:那么如果你想要VS10支持,你真的不想要C++ 11. (4认同)
  • @spraff:我不同意亲切,标题谈到遍历一个容器,范围为基础的循环迭代肯定在容器中,同时从多个微小的错误,任何其他环可能会受到屏蔽你.OP提供的代码示例实际上并不涉及迭代容器(更多来自它的迭代器......)但问题仍然存在. (3认同)

spr*_*aff 24

更好的方法是

begin(container)
end(container)
Run Code Online (Sandbox Code Playgroud)

因为它更具可扩展性.例如,模板参数推导可用于确定一个静态数组的大小并因此begin(my_static_array)end(my_static_array)将工作.

更一般地,您可以添加重载/特化以开始(.)end(.)并在通用算法中使用不可变遗留类型.

如果你自己编写通用算法,你真的只需要担心这个问题

template <typename T>
void foo (T & t)
{
    bar (begin(t), end(t)); // certainly better than bar(t.begin(), t.end())
}
Run Code Online (Sandbox Code Playgroud)

在客户端代码中,它并不重要.事实上,我会说在这种情况下不要使用新形式 - 我喜欢在某些情况下保留某些风格/习语,划分我的心态.但那只是我.

for (auto i = c.begin(); i != c.end(); ++i)
   // I can see at-a-glance that c is a STL-style container.
   // That might be useful to know. I can probably dismiss static arrays
   // and unorthodox containers as possibilities.
   foo (i, c.size());
Run Code Online (Sandbox Code Playgroud)

  • 如果要在数组上启用迭代,则必须编写`std :: begin(t)`和`std :: end(t)`,否则必须编写`using std :: begin;`和`使用std :: end;`作为函数内部的前两个语句(类似于`using std :: swap` idiom). (4认同)
  • @MatthieuM.,或者我可以让编译器担心微观优化并拒绝用噪声来装饰我的答案. (4认同)