2009-03-12 33 views
6

No puedo encontrar esta pregunta en stackoverflow. Pero me pregunto cómo las personas usan STL (sin impulso extravagante) ... solo un viejo STL. Trucos/consejos/casos más usados ​​adquiridos durante muchos, muchos años ... y quizás trampas ...algoritmo de STL más utilizado, predicados, iteradores

Vamos a compartir que ...

Un consejo por respuesta ... con ejemplo de código -

Editar ¿es una pregunta tan mala ya que resulta en votos a favor?

+1

puedo encontrar esta pregunta realmente útil. Sin embargo, está lleno de respuestas inútiles ... +1 a todos los que contribuyeron. – AndreasT

Respuesta

7

Uso el STL en casi todos mis proyectos, para cosas desde bucles (con iteradores) hasta la división de la entrada en un programa.

Tokenise una cadena de entrada por espacios e introducir el resultado en un std :: vector para analizar más tarde:

std::stringstream iss(input); 
std::vector<std::string> * _input = new std::vector<std::string>(); 

std::copy(std::istream_iterator<std::string>(iss), 
      std::istream_iterator<std::string>(), 
      std::back_inserter<std::vector<std::string> >(*_input)); 

Otros favoritos fuera de curso son std :: revertir y varios otros algoritmos definidos en <algorithm>.

6

Usando el vector para reemplazar el puntero + nuevo. Eso es enorme.

algoritmo
3

más útil (en mi humilde opinión) - std :: for_each

9

Mi favorito es el siguiente para cambiar nada en flujo continuo en una cadena:

template <class TYPE> std::string Str(const TYPE & t) { 
    std::ostringstream os; 
    os << t; 
    return os.str(); 
} 

continuación:

string beast = Str(666); 
+0

boost :: lexical_cast: P –

+2

ver pregunta original - boost no permitido –

+0

pero esa es más o menos exactamente la fuente de lexical_cast –

1

Hay no se usan los algoritmos, predicados o iteradores STL más utilizados. Es como preguntar cuál es el operador más utilizado en lenguaje C++. ¿Qué usa con más frecuencia, operator+ o operator-? ¿Prefieres if a while? O tal vez a throw?

Todo se usa cuando se tiene que usar.

PD: Le sugiero que lea Effective STL de Scott Meyers antes de hacer estas preguntas.

+1

tengo ese libro –

+0

Entonces me sorprende que hayas hecho esta pregunta :) Realmente :) – Paul

+3

Decirle a la gente que es tonto por hacer una pregunta no es útil. – catphive

1

Pregunta a pintor "¿Cuál es tu pincel favorito/más usado?" :)

+0

Si insinúa que es inútil, no estoy de acuerdo. También se preocupan por las materias primas que usan. Los expresionistas usaban pinceles grandes para hacer trazos bruscos, los pintores realistas usaban los más finos y tal vez los lápices, etc. Existen diferencias similares en la programación. – Frank

+0

Quise decir que STL tenía diferentes herramientas para diferentes objetivos. No podemos comparar, la herramienta que necesitaba dependía de mi tarea actual. – bayda

+0

Soy pintor ... y también programador. Puedo decirles que los pintores a menudo discuten sus cepillos, herramientas y técnicas favoritas. – Benj

2

No puedo recordar tener un algoritmo/predicado/iterador favorito o el más utilizado, solo el que hizo el mejor trabajo para lo que estaba tratando de lograr en ese momento.

4

I love vector. Es lo que las matrices de C++ deberían haber sido. Aunque hago mucho trabajo en tiempo real. Las personas que no necesitan determinisim pueden preferir la lista.

Casi todo el mundo usa el diablo de cuerdas.

No llego a usar mucho el algoritmo, ya que todavía usamos VS6 aquí (que no puede manejar las complejas instancias de plantilla). Eso pasará pronto sin embargo.

2

El functional cosas: bind1st, bind2nd, mem_fun, equal_to, etc., es muy útil si por alguna razón no se tiene acceso a impulsar Enlazar.

Es una pregunta muy subjetiva y depende mucho del estilo de codificación de su equipo, tipo de proyecto y otros factores desconocidos.

6

Me encantan el istream_iterator y el ostream_iterator.

Una manera fácil agradable de leer un arroyo y haciendo que parezca cualquier otro recipiente:

// Copies a stream of integers on the std input 
// into a vector. 
int main() 
{ 
    std::vector<int> data; 
    std::copy(std::istream_iterator<int>(std::cin), 
       std::istream_iterator<>(), 
       std::back_inserter(data) 
      ); 

    // By uisng the istream_iterator<> the input just becomes another container. 
} 
+0

¡Oh, esto es realmente agradable! no sabía acerca de esta opción, ¡gracias! – petric

1

El siguiente es un tanto "mal", pero nos ha salvado de muchos errores.

(Actualización, gracias al comentario de @Ricky65 por traerme de vuelta aquí.) C++ 11 tiene un range-based for loop que es muy superior a esto, si su compilador lo admite; sin embargo, todavía trabajamos con algunos compiladores antiguos de realmente.

 
#define FOREACH(iter,stlContainer) \ 
for (typeof(stlContainer.begin()) iter = stlContainer.begin(), \ 
            iter##End_Cached = stlContainer.end(); \ 
     iter != iter##End_Cached; \ 
     ++iter) 

(actualizarse una vez más, el crédito a los desarrolladores de Boost.) Se basa libremente en el más complicado, pero más capaz BOOST_FOREACH macro, pero tiene la ventaja de ser mucho más fácil con el paso a través de versiones de depuración de los casos pequeños, y no requiere una pequeña pila de encabezados boost (que en algunas bases de código/grupos está prohibida).

Usando std::for_each es preferible, en general, pero tiene algunas desventajas:

  • los usuarios deben saber mucho acerca de las interacciones entre bind1st/bind2nd/ptr_fun/mem_fun utilizarla de manera eficaz para la "visita" no trivial - boost soluciona muchos de estos problemas, pero no todos tienen o saben aumentar
  • usuarios pueden necesitar proporcionar su propio functor (por lo general una estructura) para un solo punto de uso; dichas estructuras no se pueden declarar dentro de la función que rodea el bucle, lo que lleva a la "no localidad" del código relacionado; no lee tan bien como tener la lógica en línea con el flujo del resto de la función en algunos casos
  • que no siempre muy bien en línea, dependiendo del compilador

La macro FOREACH como se indica anteriormente, proporciona un par de cosas:

  • como std::for_each, usted no conseguirá sus límites de test incorrecto (no iterar uno pasado el final, etc.)
  • usará const_iterators sobre contenedores constantes

Tenga en cuenta que no requiere una extensión "typeof" algo no estándar.

Un uso típico podría ser:

 
list< shared_ptr<Thing> > m_memberList; 
// later 
FOREACH(iter, m_memberList) 
{ 
    if ((*iter)->getValue() < 42) { 
     doSomethingWith(*iter); 
    } 
} 

no estoy del todo contento con esta macro, pero ha sido muy valiosa aquí, especialmente para los programadores sin tanta experiencia en el diseño STL-conscientes.

(Por favor no dude en señalar ventajas/desventajas/defectos, voy a actualizar la respuesta.)

+0

Ja, la macro falta algunos parches de seguridad, actualizará eso en un momento. Por supuesto, los "contras" usuales del macro uso se aplican todos: evaluaciones repetidas, etc., etc. – leander

+0

Oh. Vale la pena señalar que este ciclo elige evitar evaluaciones repetidas de end(). Puede o no ser sabio dependiendo de lo que estés haciendo en el ciclo. Por supuesto, modificar el contenido de un contenedor mientras itera es siempre una proposición difícil ... – leander

+1

Al leer esto en 2013, me alegro de que range-for haya sido agregado en C++ 11. ¡Esa macro es asqueroso! – Ricky65

Cuestiones relacionadas