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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8452130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:35:18  来源:igfitidea点击:

When to use std::begin and std::end instead of container specific versions

c++c++11

提问by mark

Are there any general preferences or rules that explain when container specific versions of begin and end should be used instead of free functions std::beginand std::end?

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

It is my understanding that if the function is a template whereby the container type is a template parameter then std::beginand std::endshould be used, i.e.:

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

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

What about in other scenarios such as a standard / member function where the type of container is known? Is it still better practice to use std::begin(cont)and std::end(cont)or should the container's member functions cont.begin()and cont.end()be preferred?

在其他场景(例如容器类型已知的标准/成员函数)中呢?它仍然是更好的做法是使用std::begin(cont)std::end(cont)或应容器的成员函数cont.begin()cont.end()首选?

Am I correct in assuming that there is no benefit in performance by calling cont.end()over std::end(cont)?

我在假设有通过调用在性能上没有任何好处纠正cont.end()std::end(cont)

采纳答案by Moo-Juice

If you look at, say, the definition of std::begin:

如果你看一下,比方说,的定义std::begin

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

You see that all it does is reference the begin()anyway. I suppose a decent compiler will make the difference nil, so I guess it comes down to preference. Personally, I'd use cont.begin()and cont.end()just so that I wouldn't have to explain it to anybody :)

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

As Mooing Duck points out, however, std::beginalso works on arrays:

然而,正如 Mooing Duck 所指出的,它std::begin也适用于数组:

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

... so there is that to consider. If you are notusing arrays, I'd go with my suggestion. However if you are unsure if what is passed is going to be an STL container, or an array of <T>, then std::begin()is the way to go.

......所以要考虑。如果您使用数组,我会同意我的建议。但是,如果您不确定传递的内容是 STL 容器还是 的数组<T>,那么std::begin()这就是要走的路。

回答by David Rodríguez - dribeas

The free function version is more generic than the member function of the container. I would use it probably in generic code where the type of the container is not known before hand (and might be an array). In the rest of the code (i.e. when the container is fixed and known) I would probably use c.begin()due to inertia. I would expect new text books on C++ to recommend the free function version (as it is never worse and sometimes better), but that has to catch up with common usage.

免费函数版本比容器的成员函数更通用。我可能会在通用代码中使用它,其中容器的类型事先未知(并且可能是一个数组)。在代码的其余部分(即当容器固定且已知时),c.begin()由于惯性,我可能会使用。我希望有关 C++ 的新教科书推荐免费函数版本(因为它永远不会更糟,有时甚至更好),但这必须赶上常见用法。

回答by Jon Hanna

Barring some optimisations being turned off to debug, there won't be a performance benefit to using cont.begin()(or getting a pointer to the first element, or whatever) unless someone's provided a really weird implementation! Pretty much all implementations (and certainly those with STL) are wafer-thin and melt in the compiler's mouth.

除非关闭一些优化以进行调试,否则使用cont.begin()(或获取指向第一个元素的指针或其他任何内容)不会有性能优势,除非有人提供了一个非常奇怪的实现!几乎所有的实现(当然还有那些使用 STL 的实现)都非常薄,并且在编译器的嘴里融化了。

The plus-side is in the "or whatever" above: The same code works across different collection types whether another from the STL, or arrays, or some bizarre collection by a third party if they thought to supply a specialisation of begin for it. Even if you never use that, begin()is well-known enough that there should be a familiarity benefit.

优点在于上面的“或任何”:相同的代码适用于不同的集合类型,无论是来自 STL 的另一个,还是数组,或者第三方的一些奇怪的集合,如果他们想为它提供 begin 的专业化。即使你从不使用它,begin()也应该有一个熟悉的好处。