自动参考的类型

时间:2014-06-05 11:53:16

标签: 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

当我将鼠标悬停在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

3 个答案:

答案 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
    }
}

因此,您可以看到,在您的情况下,ij的类型是从*it的类型中推导出来的,其中itstd::vector迭代器。 std::vector迭代器是实现定义的,但*it的结果不是。


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

  

类或指针类型X满足前锋的要求   迭代器,如果

     
      
  • ...
  •   
  • 如果X是可变迭代器,reference是对T的引用;如果X是常量迭代器,则reference是对const T的引用,
  •   

reference24.4.4/2 [iterator.iterators]中使用*it来表示i的返回类型。


因此,对于您的情况,标准要求int的类型为jint&的类型为{{1}}。这可能是MSVC ++的情况,而智能感知无法正确解析类型。


编辑:修正了取消引用迭代器时返回类型的答案。

答案 1 :(得分:8)

IntelliSense让您了解std::vector的实施情况。这是一种复杂的方式,可以引用std::vector<int>::value_type,或者在这种情况下,引用int

答案 2 :(得分:7)

是的,它是int。所有这一切都意味着智能感到困惑并放弃了。

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