std :: begin和end的const重载的目的是什么? [英] What is the purpose of the const overloads of std::begin and end?

查看:310
本文介绍了std :: begin和end的const重载的目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆