tipos - referencias c++
Tipo de referencia automática (3)
IntelliSense le está dando un vistazo a la implementación de std::vector
. Esa es una forma complicada de decir referencia a std::vector<int>::value_type
o, en este caso, referencia a int
.
Si tengo los siguientes dos bucles:
std::vector<int> v;
for(auto i : v)
//do something with i
for(auto& j : v)
//do something with j
Cuando coloco sobre i
, intellisense lo muestra como int i
(como se esperaba). Sin embargo, cuando me coloco sobre j
no obtengo int&
como esperaba, sino que
std::_Simple_types<std::_Wrap_alloc<std::_Vec_base_types<int, std::allocator<int> >::_Alloc>::value_type>::value_type &j
¿Qué es esta definición complicada? ¿Es lo mismo que int&
? Si no, ¿qué es? Y si lo es, ¿por qué puede deducir int
solo para i
, pero no int&
for j
?
Los estados estándar en 6.5.4 [stmt.ranges]
:
Para una declaración basada en el rango del formulario
for ( for-range-declaration : expression ) statement
deja que
range-init
sea equivalente a la expresión entre paréntesis
( expression )
En cada caso, una declaración basada en rango es equivalente a
{ auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
Así que puedes ver que en tu caso los tipos de i
y j
se deducen del tipo de *it
en el it
es un iterador de std::vector
. std::vector
iteradores std::vector
están definidos por la implementación, sin embargo, el resultado de *it
es.
Como se indica en los comentarios, un iterador de std::vector
es un iterador directo, y después de 24.2.5/1 [forward.iterators]
:
Una clase o tipo de puntero
X
satisface los requisitos de un iterador hacia adelante si
- ...
- si X es un iterador mutable, la
reference
es una referencia aT
; siX
es un iterador const, lareference
es una referencia aconst T
,
Aquí se usa la reference
en 24.4.4/2 [iterator.iterators]
para indicar el tipo de retorno de *it
.
Por lo tanto, para su caso, el estándar requiere que el tipo de i
sea int
y el tipo de j
sea int&
. Este es probablemente el caso de MSVC ++, e intellisense simplemente no puede resolver correctamente el tipo.
Editar: se arregló la respuesta con respecto al tipo de retorno al eliminar la referencia de iteradores.
Sí, es int
. Todo lo que significa es inteligible, se confundió y se rindió.
Intellisense no es perfecto: incluso puedes usar el código de compilación ondulado rojo.