2009-04-09 12 views
23

Estoy buscando ejemplos prácticos y educativos de la adaptación del código C++/STL en pocas líneas. Mis favoritos reales son:Trazadores de líneas STL más útiles o increíbles

  1. vacía un vector liberar la memoria reservada:

    vector <...>().swap (v) 
    

    (swap con una temporal)

  2. Copiar un mapa de un vector:

    map<T1, T2> myMap; 
    vector< pair<T1, T2> > myVec(myMap.begin(), myMap.end()); 
    // or 
    myVec.assign(myMap.begin(), myMap.end()); 
    
  3. Personalizado, sin división:

    vector<string> &mysplit(const string &s, char delim, vector<string> &elems) { 
        stringstream ss(s); 
        string item; 
        while(getline(ss, item, delim)) { elems.push_back(item); } 
        return elems; 
    } 
    

Respuesta

6
// std::back_inserter usage (std::inserter for map) 
std::copy(source.begin(), source.end(), std::back_inserter(container)); 

-

// mem_fun and bind usage (but boost better) 
std::some_algorithm(..., std::mem_fun(func)); 

no tan útil, pero poderosa:

cheque es contenedor ordenadas

std::adjacent_find(container.begin(), container.end(), greater<Container::value_type>()) == container.end() 

también los ejemplos mencionados por usted y dirkgently.

+0

El example_find example es ingenioso. –

+2

+1 para adyacencias_find() :) –

2
copy(istreambuf_iterator<char>(cin), istreambuf_iterator<char>(), 
    ostream_iterator<char>(cout)); 

Otra expresión utilizada frecuentemente se está iniciando un contenedor desde una matriz:

#include <map> 
using namespace std; 

int main() { 
    typedef std::map<char,int> LUT; 
    typedef LUT::value_type LUT_item_t; 

    const LUT_item_t items[] = { LUT_item_t('b',1), 
           LUT_item_t('a',5) 
           }; 

    LUT my_map(items, items + sizeof items/sizeof items[0]); 
    return 0; 
} 

Pero si quieres magia pura, mira en Boost Lambda Library;) Una muestra:

vector<int*> vp(10); 
sort(vp.begin(), vp.end(), *_1 > *_2); 
+0

Error común aquí. Como istream_iterator usa el operador >>, se eliminará el espacio en blanco. Para compensar esto, debe usar istreambuf_iterator para asegurarse de conservar el espacio en blanco. –

+0

@Martin York: Correcto. Lo arreglaré. – dirkgently

1

Para su segundo ejemplo utilizar el tipo de valor:

#

Copy a map to a vector: 

typedef map<T1, T2> MyMap; 
MyMap myMap; 
vector<MyMap::value_type> myVec(myMap.begin(), myMap.end()); 
13

Mi favorito es copiar los contenedores a la salida: y la copia de la secuencia de entrada en un recipiente.

#include <vector> 
#include <algorithm> 
#include <iterator> 
#include <iostream> 

int main() 
{ 
    std::vector<int> data; 
    std::copy(std::istream_iterator<int>(std::cin), 
       std::istream_iterator<int>(), 
       std::back_inserter(data) 
      ); 

    std::copy(data.begin(),data.end(), 
       std::ostream_iterator<int>(std::cout,"\n") 
      ); 
} 
7

La siguiente idioma se necesita para eliminar en realidad los elementos eliminados por remove() o remove_if():

vector<int> v; 
... 
v.erase(remove(v.begin(), v.end(), 42), v.end()); 

remove() y remove_if() sólo deslice elementos no retirados hacia adelante e informar donde termina la nueva gama - que no los elimine (y no puede) porque pueden funcionar en cualquier rango arbitrario de iteradores, no solo en un contenedor.

2

Lo que más me gusta es usar bind1st/bind2nd/mem_fun en tipo de delegados.

// will call a->func(v[i]) 
for_each(v.begin(), v.end(), bind1st(mem_fun(&A::func), &a)); 

// will call w[i]->func(72) 
for_each(w.begin(), w.end(), bind2nd(mem_fun(&A::func), 72)); 

El uso del refuerzo y la función son mucho mejores, pero es impresionante lo que se puede hacer con solo STL.

+1

Probablemente seleccione su publicación como una respuesta aceptada ahora. Sin embargo, sería un poco político, porque lo que me gustaría mostrar con esta aceptación es que boost :: bind se usa en exceso en situaciones simples donde STL es suficiente. –

+0

Una vez que tiene boost :: bind a su disposición, no veo ninguna necesidad de volver a los enlazadores originales de STL. Son muy primitivos. – StilesCrisis

0

Me gusta esta opción para recorrer cada línea de un archivo.De una columna de Andrew Koenig en Dr. Dobbs.

for (string s; getline(stream,s);) { 
    // Process line 
} 
0

El uso de std :: for_each en combinación con una función lambda (puesto que C++ 11)

std::vector<int> v(20); 

std::for_each(v.begin(), v.end(), [] (int item) 
{ 
    std::cout << item; 
}); 

en lugar de

for(std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) 
{ 
    std::cout << *it; 
} 

hace para verse mejor bucles.

Cuestiones relacionadas