libreria iterador español ejemplo c++ c++11

iterador - stl c++ español



Cuándo usar std:: begin y std:: end en lugar de versiones específicas del contenedor (3)

La versión de la función gratuita es más genérica que la función miembro del contenedor. Lo usaría probablemente en un código genérico donde el tipo de contenedor no se conoce de antemano (y podría ser una matriz). En el resto del código (es decir, cuando el contenedor es fijo y conocido) probablemente usaría c.begin() debido a la inercia. Esperaría que los nuevos libros de texto en C ++ recomendaran la versión de la función gratuita (ya que nunca es peor y, a veces, mejor), pero eso tiene que ponerse al día con el uso común.

Esta pregunta ya tiene una respuesta aquí:

¿Existen preferencias generales o reglas que expliquen cuándo se deben usar versiones específicas de contenedor de inicio y fin en lugar de las funciones libres std::begin y std::end ?

Entiendo que si la función es una plantilla donde el tipo de contenedor es un parámetro de plantilla, se deben usar std::begin y std::end , es decir:

template<class T> void do_stuff( const T& t ) { std::for_each( std::begin(t), std::end(t), /* some stuff */ ); }

¿Qué sucede en otros escenarios, como una función estándar / miembro, donde se conoce el tipo de contenedor? ¿Sigue siendo una mejor práctica usar std::begin(cont) y std::end(cont) o deberían las funciones de miembro del contenedor cont.begin() y cont.end() ser preferidas?

¿Estoy en lo correcto al asumir que no hay beneficio en el rendimiento llamando a cont.end() sobre std::end(cont) ?


Salvo que algunas optimizaciones se desactiven para depurar, no habrá un beneficio de rendimiento al usar cont.begin() (o al cont.begin() el primer elemento, o lo que sea) a menos que alguien haya proporcionado una implementación realmente extraña. Prácticamente todas las implementaciones (y ciertamente aquellas con STL) son muy delgadas y se derriten en la boca del compilador.

El lado positivo está en el "o lo que sea" anterior: el mismo código funciona en diferentes tipos de colecciones, ya sea otro de STL, o matrices, o alguna colección extraña de un tercero si pensaban proporcionar una especialización de comenzar por ella. Incluso si nunca usa eso, begin() es lo suficientemente conocido como para que haya un beneficio de familiaridad.


Si nos fijamos en, digamos, la definición de std::begin :

template< class C > auto begin( C& c ) -> decltype(c.begin());

Usted ve que todo lo que hace es hacer referencia al begin() todos modos. Supongo que un compilador decente hará la diferencia nula, así que supongo que se trata de preferencia. Personalmente, usaría cont.begin() y cont.end() solo para no tener que explicárselo a nadie :)

Sin embargo, como señala Mooing Duck, std::begin start también funciona en matrices:

template< class T, size_t N > T* begin( T (&array)[N] );

... así que hay que considerar. Si no está utilizando matrices, iré con mi sugerencia. Sin embargo, si no está seguro de si lo que se va a pasar será un contenedor STL o una matriz de <T> , entonces std::begin() es el camino a seguir.