c++ open-source stl

¿Ejemplos de "C++ moderno" en acción?



open-source stl (7)

Adobe ha publicado una gran cantidad de código abierto de código abierto moderno en los últimos años, que probablemente valga la pena verificar:

http://opensource.adobe.com/wiki/display/site/Home

Creo que su biblioteca GIL ha sido o está en proceso de ser agregada a Boost. su STLab contiene un montón de funcionalidades que, por lo que he visto, es muy limpio y muy similar al estilo STL.

He estado usando construcciones C ++ más "modernas" por un tiempo, pero superficialmente y no en todas partes. Estoy buscando proyectos de código abierto para estudiar que son buenos ejemplos del uso moderno de C ++ y STL.

Cosas como las sugeridas en el "STL efectivo" de Meyer, como tratar de evitar los bucles y reemplazarlos con construcciones más funcionales, usando boost :: bind y boost :: function, etc. Estos aún me parecen un poco antinaturales, y cuando tengo que hacer algo rápido y trabajo, tiendo a volver a libc y string.h (puedes agarrar mi strtok cuando lo levantas de mis manos frías y muertas).

Sin embargo, también he tenido la experiencia positiva de encontrar lo que sería un cambio drástico simplificado porque he usado estos constructos, o puedo implementar algo con solo unas pocas líneas de código, porque tenía los operadores correctos y los funtores mintiendo. alrededor. Además, recientemente he estado prestando más atención a la concurrencia, por lo que esto se está volviendo aún más importante para mí.

¿Me pueden recomendar algunos ejemplos de proyectos de código abierto bien escritos que hacen un uso intensivo de la STL y otras técnicas modernas de C ++ que podría estudiar? Estoy particularmente interesado en el código de la aplicación, explorar las fuentes de Boost ha sido útil, pero es por necesidad muy general porque es un código de biblioteca.

Estoy interesado en proyectos medianos a grandes, al menos unas pocas decenas de miles de líneas. Es bastante fácil encontrar ejemplos que tienen cientos de líneas, pero eso no es demasiado útil.



Aquí hay un fragmento para concatenar el vector de cadenas en una cadena:

vector<string> vecstr; vecstr.push_back("abc"); vecstr.push_back("efg"); // etc. string concat = accumulate( vecstr.begin(), vecstr.end(), string("") );


De hecho, eché un vistazo a Google Chrome y lo recomendaría. Las guidelines codificación de C ++ de Google son un buen andamio para proyectos grandes. También son utilizados / adoptados en nuestro equipo. Además, estoy muy contento de que estén proporcionando sus frameworks de testing y mocking C ++ como proyectos de código abierto. Muy útil para grandes proyectos en los que se pierden muchas de las agradables pruebas del mundo Java / Managed.


Meyers está bien, sin embargo, si realmente quieres esforzarte, tienes que leer:

Andrei Alexandrescu - Diseño moderno en C ++: programación genérica y patrones de diseño aplicados

¡Va a sorprenderte por completo! Lo que aprendes en el libro describe la biblioteca Loki .

Uno de mis favoritos es las conversiones int-to-type:

template <int v> struct Int2Type { enum { value = v }; };

Lo he usado en el pasado para mi biblioteca de serialización XML de C ++ para preasignar vectores <> antes de cargarlos con datos:

// We want to call reserve on STL containers that provide that function, // namely std::vector. // However, we would get a compiler error if we tried to call reserve on // an STL container that // did not provide this function. This is the solution. template <bool b, class T> class CReserve { public: static void reserve(T &lst, const int &n) { reserve(lst, n, Loki::Int2Type<b>()); } private: static void reserve(T &lst, const int &n, Loki::Int2Type<true>) { lst.reserve(n); } static void reserve(T &lst, const int &n, Loki::Int2Type<false>) { (void)lst; (void)n; } };

Observe las especializaciones privadas arriba. Bueno, si miras con atención, una llama a reserva (), y la otra no. Esta es una especialización de plantilla que usa un bool como tipo.

que a su vez es utilizado por:

template <bool bCallReserve, class T> bool STLSerializeClassType(MSXML::IXMLDOMNodePtr pCurNode, T &lst, CXmlArchive &archive, const char *name) { if(archive.IsStoring()) { ... } else { lst.clear(); T::size_type nCount(0); XML_ELEMENT(nCount); CReserve<bCallReserve, T>::reserve(lst, nCount); while(nCount--) { T::value_type temp; temp.SerializeXml(archive, pCurNode); lst.push_back(temp); } } }

Para simplificar las cosas en el código C ++ de los usuarios, agregué muchas definiciones de ayuda:

#define SERIALIZE_XML_STL_CLASS(list_name, bCallReserve) / (HS::STLSerializeClassType<(bCallReserve)> (pCurNode, (list_name), archive, (#list_name)) )

Entonces en tu código usarías algo como:

std::list<CFred> fredList; SERIALIZE_XML_STL_CLASS(fredList, false);

O para vectores:

vector<CFred> fredList; SERIALIZE_XML_STL_CLASS(fredList, true);

De todos modos, dejaré de hablar sobre ... Eso es solo poner en práctica la sencilla plantilla Int2Type <>. Hay muchas cosas ingeniosas como hacer que el compilador calcule un montón de cosas de antemano mediante el uso inteligente de enumeraciones. Es un libro realmente increíble.


No es realmente proyectos, pero aquí hay un par de fragmentos:

Uso de muestra de boost :: thread / boost :: bind:

class X { void expensive_operation( int argument ); }; int main() { X x; boost::thread thr( boost::bind( &X::expensive_operation, &x, 1000 ) ); std::cout << "Thread is processing..." << std::endl; thr.join(); }

std :: copy, std :: transform, BOOST_FOREACH:

int main() { std::vector<std::string> v; std::copy( std::istream_iterator<std::string>( std::cin ), std::istream_iterator<std::string>(), std::back_inserter(v) ); BOOST_FOREACH( std::string & s, v ) { transform(s.begin(), s.end(), s.begin(), toupper); } std::copy( v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, " ") ); }

El fragmento leerá de la entrada del usuario un conjunto de cadenas en un vector. Luego, para cada cadena en el vector, se convertirá en mayúscula y finalmente dará salida al resultado.

Nuestras aplicaciones hacen un uso intensivo de boost :: signals y boost :: function para desacoplar clases donde no es crítico en el tiempo, principalmente en las clases de UI:

class ContactDetailPanel; class ContactListPanel { public: void update(); void edit_completed( bool change ); boost::function< void ( Contact & ) >& edit_contact(); }; int main() { ContactListPanel clp; ContactDetailPanel cdp; clp.edit_contact() = boost::bind( &ContactDetailPanel::edit, &cdp, _1 ); cdp.edit_completed() = boost::bind( &ContactListPanel::edit_completed, &clp, _1 ); ui::signal_update().connect( boost::bind( &ContactListPanel::update, &clp ) ); }

Cada panel no tiene información sobre otros paneles. El código que une los paneles tiene el conocimiento del flujo (para editar un panel de detalles de contactos de contacto, notificar la finalización de la edición al panel de la lista de contactos). Además, hay una señal global para notificar a los paneles sobre las actualizaciones del modelo subyacente.

Esto es especialmente útil cuando necesita escribir un código de prueba. No es necesario implementar clases simuladas para reemplazar el código de trabajo para la prueba. Las pruebas simplemente crean una instancia de la clase y conectan las funciones / señales al código de prueba sin que la clase probada advierta, siguiendo el principio de mínima intrusión durante las pruebas.


No estoy seguro acerca de "bien escrito", pero hay algunas cosas como Hypertable y KFS que son software a nivel de sistema que usan Boost y STL extensamente.

He escuchado algunas cosas sobre OpenOffice y Google Chrome, pero no he examinado su código fuente para saber con cuánta precisión usan STL. Eché un vistazo a KDE pero no necesariamente llamaría a ese C ++ moderno. Puedo decirte que un código en el que estoy trabajando está haciendo mucho C ++ moderno, pero desafortunadamente no es de código abierto, aunque creo que es cuestión de tiempo y paciencia sacar el enfoque moderno de C ++ y tener más proyectos de código abierto. adoptando los modismos.