何时使用std :: begin和std :: end而不是容器特定版本

是否有任何一般的喜好或规则解释什么时候应该使用容器特定的开始和结束版本而不是自由函数std::beginstd::end

这是我的理解,如果函数是一个模板,其中容器types是一个模板参数,那么应该使用std::beginstd::end ,即:

 template<class T> void do_stuff( const T& t ) { std::for_each( std::begin(t), std::end(t), /* some stuff */ ); } 

在其他情况下,如容器的types已知的标准/成员函数呢? 使用std::begin(cont)std::end(cont)还是更好的做法,或者容器的成员函数cont.begin()cont.end()是首选?

我通过调用std::end(cont) cont.end()来假设没有任何好处吗?

如果你看一下std::begin的定义:

 template< class C > auto begin( C& c ) -> decltype(c.begin()); 

你看它所做的只是引用begin() 。 我想一个体面的编译器会使差异零,所以我想它归结为偏好。 就个人而言,我会使用cont.begin()cont.end() ,这样我就不必向任何人解释:)

正如Mooing Duck指出的那样, std::begin也适用于数组:

 template< class T, size_t N > T* begin( T (&array)[N] ); 

…所以有这个考虑。 如果你使用数组,我会去我的build议。 但是,如果您不确定传递的是STL容器还是<T>数组,那么std::begin()就是要走的路。

自由函数版本比容器的成员函数更通用。 我会使用它可能在容器的types之前不知道的通用代码(也可能是一个数组)。 在代码的其余部分(即当容器是固定的和已知的)我可能会使用c.begin()由于惯性。 我期望C ++的新书推荐免费的function版本(因为它永远不会更糟,有时更好),但是它必须赶上常见的用法。

除非某些优化被closures以进行debugging,否则使用cont.begin() (或者获取指向第一个元素的指针,或其他)将不会有性能优势,除非有人提供了一个非常奇怪的实现! 几乎所有的实现(当然也包括STL)都是薄的,在编译器的口中融化。

正面是在上面的“或什么”:相同的代码工作跨不同的集合types,无论是从STL或数组,或一些奇怪的收集第三方,如果他们认为提供专业化的开始。 即使你从来没有使用过, begin()已经足够熟悉,应该有一个熟悉的好处。