如果我有以下两个循环:
std::vector<int> v;
for(auto i : v)
//do something with i
for(auto& j : v)
//do something with j
当我将鼠标悬停在i
上时,智能感知会将其显示为int i
(正如预期的那样)。但是,当我将鼠标悬停在j
上时,我没有像我预期的那样得到int&
,而是
std::_Simple_types<std::_Wrap_alloc<std::_Vec_base_types<int, std::allocator<int> >::_Alloc>::value_type>::value_type &j
这个复杂的定义是什么?它与int&
相同吗?如果没有,那是什么?如果是,为什么它只能为int
推导i
,而int&
只推导j
?
答案 0 :(得分:11)
6.5.4 [stmt.ranges]
中的标准状态:
对于基于范围的表格形式
for ( for-range-declaration : expression ) statement
让
range-init
等同于包围的表达式 括号( expression )
在每种情况下,基于范围的for语句等同于
{ auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
因此,您可以看到,在您的情况下,i
和j
的类型是从*it
的类型中推导出来的,其中it
是std::vector
迭代器。 std::vector
迭代器是实现定义的,但*it
的结果不是。
如评论中所示,std::vector
迭代器是一个前向迭代器,在24.2.5/1 [forward.iterators]
之后:
类或指针类型
X
满足前锋的要求 迭代器,如果
- ...
- 如果X是可变迭代器,
reference
是对T
的引用;如果X
是常量迭代器,则reference
是对const T
的引用,
reference
在24.4.4/2 [iterator.iterators]
中使用*it
来表示i
的返回类型。
因此,对于您的情况,标准要求int
的类型为j
,int&
的类型为{{1}}。这可能是MSVC ++的情况,而智能感知无法正确解析类型。
编辑:修正了取消引用迭代器时返回类型的答案。
答案 1 :(得分:8)
IntelliSense让您了解std::vector
的实施情况。这是一种复杂的方式,可以引用std::vector<int>::value_type
,或者在这种情况下,引用int
。
答案 2 :(得分:7)
是的,它是int
。所有这一切都意味着智能感到困惑并放弃了。
智能感知并不完美:你甚至可以把它变成红色波浪形的编译代码。