#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>>()
产生一个右值表达式,可以表示为:
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
对于右值表达式,只有第二个重载 (#2) 是可行的——右值不能被非 const 左值引用绑定(bind)。引用类型的 const 限定意味着编译器将使用 begin
的 const 限定重载。成员函数:
const_iterator begin() const noexcept;
// ~~~~^
返回 const_iterator
类型的实例.
您可以通过请求 std::vector<int>
的左值表达式来更改该行为。来自 std::declval
调用:
decltype(std::begin(std::declval<std::vector<int>&>())) pos_1 = coll.begin();
// ~~^~~
关于c++ - 为什么 "std::begin()"在这种情况下总是返回 "const_iterator"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42580761/