自动参考的类型

Bar*_*uch 19 c++ visual-studio c++11 visual-studio-2013

如果我有以下两个循环:

std::vector<int> v;

for(auto i : v)
  //do something with i

for(auto& j : v)
  //do something with j
Run Code Online (Sandbox Code Playgroud)

当我将鼠标悬停在上面时i,intellisense会将其显示为int i(如预期的那样).但是,当我将鼠标悬停在上面时,j我并没有int&像预期的那样得到,而是

std::_Simple_types<std::_Wrap_alloc<std::_Vec_base_types<int, std::allocator<int> >::_Alloc>::value_type>::value_type &j
Run Code Online (Sandbox Code Playgroud)

这个复杂的定义是什么?它是一样的int&吗?如果没有,那是什么?如果是,为什么它只是推断inti,但不int&j

Dan*_*vil 11

标准规定6.5.4 [stmt.ranges]如下:

对于基于范围的表单声明

for ( for-range-declaration : expression ) statement
Run Code Online (Sandbox Code Playgroud)

让我们range-init相当于括号括起来的表达式

( expression )
Run Code Online (Sandbox Code Playgroud)

在每种情况下,基于范围的for语句等同于

{
    auto && __range = range-init;
    for ( auto __begin = begin-expr,  __end = end-expr;  __begin != __end; ++__begin ) {
        for-range-declaration = *__begin;
        statement
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,你可以看到你的情况的类型i,并j从类型推导*it这里it是一个std::vector迭代器.std::vector迭代器是实现定义的,但结果*it不是.


如注释中所示,std::vector迭代器是一个前向迭代器,之后24.2.5/1 [forward.iterators]:

类或指针类型X满足前向迭代器的要求

  • ...
  • 如果X是一个可变迭代器,reference则引用T; if X是一个const迭代器,reference是一个引用const T,

这里reference用于24.4.4/2 [iterator.iterators]表示返回类型*it.


因此,对于你的情况下,标准要求的类型iint和类型jint&.这可能是MSVC++的情况,而intellisense无法正确解析该类型.


编辑:修复了取消引用迭代器时有关返回类型的答案.

  • 不,那个类型是`int`,它只是一个复杂的`typedef`.`*it`为'vector`**必须是'T &`在专业化`bool`之外. (2认同)

Bla*_*ace 8

IntelliSense可以让您了解实现的方法std::vector.这是一种复杂的说法参考std::vector<int>::value_type或在这种情况下参考的方式int.


Yak*_*ont 7

是的,确实如此int.这意味着intellisense感到困惑并放弃了.

智能感知并不完美:你甚至可以把它变成红色波浪形的编译代码.

  • @Poldie实际上,自VS2010以来,Intellisense一直由EDG前端提供支持.所以它可能比VC编译器的前端更强大,但是功能被禁用,以便它们与它附带的VC版本相匹配. (2认同)