xml*_*lmx 17 c++ standards iterator type-safety c++11
#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;
}
Run Code Online (Sandbox Code Playgroud)
我的编译器是clang 4.0.输出是:
Run Code Online (Sandbox Code Playgroud)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
在这种情况下?
Pio*_*cki 21
函数调用:
std::declval<std::vector<int>>()
Run Code Online (Sandbox Code Playgroud)
得到一个rvalue表达式,可以表示为:
std::vector<int>&&
Run Code Online (Sandbox Code Playgroud)
编译器有两个(通用)重载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
Run Code Online (Sandbox Code Playgroud)
对于rvalue表达式,只有第二个重载(#2)是可行的 - rvalue不能被非const左值引用绑定.引用类型的const限定意味着编译器将使用begin
成员函数的const限定重载:
const_iterator begin() const noexcept;
// ~~~~^
Run Code Online (Sandbox Code Playgroud)
返回一个类型的实例const_iterator
.
您可以通过std::vector<int>
从std::declval
调用请求左值表达式来更改该行为:
decltype(std::begin(std::declval<std::vector<int>&>())) pos_1 = coll.begin();
// ~~^~~
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1634 次 |
最近记录: |