std :: begin和end的const重载的目的是什么? [英] What is the purpose of the const overloads of std::begin and end?
问题描述
对于 std :: begin
,我们有两个重载容器:
For std::begin
, we have two overloads for containers:
template< class C >
auto begin( C& c ) -> decltype(c.begin());
template< class C >
auto begin( const C& c ) -> decltype(c.begin());
但可以推导出 C
的一致性通过通常的模板扣除规则,所以似乎第二个重载是多余的。
But the constness of C
can be deduced by the usual template deduction rules, so it seems like the second overload is redundant. What am I missing?
推荐答案
调用 begin
end
,对于这个问题),如果我们不在容器被销毁后使用产生的迭代器。但是,将右值传递到 T&
形式的参数将不起作用,这是第二个重载发挥作用的地方。
It's reasonable to call begin
(and end
, for that matter) on an rvalue, provided we don't use the resulting iterator after the container has been destroyed. However, passing an rvalue to a parameter of the form T&
will not work, which is where the second overload comes into play.
然而,很可能我们正在处理一个前所未有的转换基于范围的提案措辞:
However, it may well be that we're dealing with a thoughtless transformation of a former range-based for proposal wording:
将以下内容添加到[container.concepts.member]的末尾:
template<Container C> concept_map Range<C> {
typedef C::iterator iterator;
iterator begin( C& c ) { return Container<C>::begin(c); }
iterator end( C& c ) { return Container<C>::end(c); } };
template<Container C> concept_map Range<const C> {
typedef C::const_iterator iterator;
iterator begin( const C& c ) { return Container<C>::begin(c); }
iterator end( const C& c ) { return Container<C>::end(c); } };
当明确的概念不会到C ++ 11,论文被修改,并且所有四个函数templo大概翻译成等效的命名空间范围函数模板。这具有接受右值的(可能无意的)结果,而原始代码只是用于区分不同限定的容器类型。
When it became clear that concepts weren't going to make it into C++11, papers were amended, and all four function temploids were presumably translated into equivalent namespace-scope function templates. This had the (potentially unintended) consequence of rvalues being accepted, while the original code was simply intended to distinguish between differently qualified container types.
请注意,现代实现 begin
/ end
会使用转发引用
Note that a modern implementation of begin
/end
would use forwarding references instead - e.g.
template <typename T>
constexpr auto begin(T&& t)
-> decltype(std::forward<T>(t).begin()) {
return std::forward<T>(t).begin();
}
这篇关于std :: begin和end的const重载的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!