繁体   English   中英

为什么“std :: begin()”在这种情况下总是返回“const_iterator”?

[英]Why does “std::begin()” always return “const_iterator” in such a case?

#include <vector>
#include <iostream>

using namespace std;

int main()
{
    vector<int> coll;

    decltype(std::begin(std::declval<vector<int>>()))
        pos_1 = coll.begin();
    auto pos_2 = coll.begin();

    cout << typeid(decltype(pos_1)).name() << endl;
    cout << typeid(decltype(pos_2)).name() << endl;
}

我的编译器是clang 4.0。 输出是:

 class std::_Vector_const_iterator<class std::_Vector_val<struct std::_Simple_types<int> > > class std::_Vector_iterator<class std::_Vector_val<struct std::_Simple_types<int> > > 

这意味着: pos_1 = pos_2; 没关系,而pos_2 = pos_1; 不行。

为什么std::begin()在这种情况下总是返回const_iterator而不是iterator

函数调用:

std::declval<std::vector<int>>()

得到一个rvalue表达式,可以表示为:

std::vector<int>&&

编译器有两个(通用)重载std::begin可供选择( [iterator.range] ):

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

template <class C> 
auto begin(const C& c) -> decltype(c.begin());  // #2

对于rvalue表达式,只有第二个重载(#2)是可行的 - rvalue不能被非const左值引用绑定。 引用类型的const限定意味着编译器将使用begin成员函数的const限定重载:

const_iterator begin() const noexcept;
//                     ~~~~^

它返回一个const_iterator类型的实例。

您可以通过从std::declval调用请求lvalue表达式std::vector<int>来更改该行为:

decltype(std::begin(std::declval<std::vector<int>&>())) pos_1 = coll.begin();
//                                             ~~^~~      

如果你有Type&& (一个临时的)那么重载决策将更喜欢const Type& over Type& ,因为临时不会绑定到非const lvalue-reference

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM