Posts

Showing posts from May, 2010

C++: Warning C4251: Templates in exported classes

Spanish version / Versión en Español Say you have a template, be it from the STL or custom, as a field in a class which is __declspec(dllexport)'ed, you'll get this warning. The problem is that we're trying to export the template's declaration without its definition. This can make our program crash in runtime if we combine binaries which use different versions of the STL or our template. This could happen if we used dll's compiled with different versions of Visual Studio. If you can't (or you're lazy) refactor your code in order not to export the class (you should only export interfaces), what you can do is export not the whole class but only the public methods which are used from other assemblies. Generically, if we have... //This generates C4251 class __declspec(dllexport) A(){ public: A(); virtual ~A(); void f(); private: std::vector<int> m_vGeneratesC4251; } ... and this dll's client assembly only needs to access f

C++: Warning C4251: Templates en clases exportadas

Versión en inglés / English version Si uno tiene un template, sea de la STL o propio, como atributo en una clase exportada con __declspec(dllexport), nos salta este warning. El problema reside en que estamos exportando la declaración del template, sin su definición. Esto puede hacer que nuestro programa explote en tiempo de ejecución si combinamos binarios con diferentes versiones de la STL o de nuestro template. Esto puede ocurrir si usamos dll's compiladas con diferentes versiones del Visual Studio. Si no podemos (o nos da fiaca) hacer refactoring para no exponer atributos en una clase exportada (idealmente, sólo deberíamos exportar interfaces), lo que podemos hacer es exportar no toda la clase sino sólo los métodos que se usan afuera. De forma genérica, si tenemos... //Esto genera C4251 class __declspec(dllexport) A(){ public: A(); virtual ~A(); void f(); private: std::vector<int> m_vGeneraC4251; } ... y el cliente de esta dll sólo necesita ac

C++: Parse input skipping whitespace

Spanish version / Versión en Español Still re-reading Stroustrup's book , I found something I'd like to have known some time ago: an elegant way to parse an input stream for words separated by whitespace (1 whitespace = any amount of consecutive space and/or tabs). This can be done using an istream_iterator, like so: #include <fstream> #include <iostream> #include <algorithm> #include <vector> void main(){ using std::cout; using std::endl; // We read from standard input, but it could just as well be a file std::istream_iterator<std::string> ii( std::cin ); cout << "--->Input whitespace-separated words:" << endl; // Suppose we stop reading when we find the word "END" std::vector<string> words; while ( *ii != "END" ){ cout << *ii << endl; words.push_back(*ii); ii++; } // Sort words cout << "Sorted words:"

C++: Parsear entrada separando palabras

Versión en inglés / English version Releyendo el libro de Stroustrup , encontré algo que me habría gustado saber tiempo atrás: una forma piola de parsear un stream de entrada separando palabras con whitespace ( 1 whitespace = cualquier cantidad consecutiva de espacios y/o tabs ). Esto se hace con un istream_iterator, así: #include <fstream> #include <iostream> #include <algorithm> #include <vector> void main(){ using std::cout; using std::endl; // Leemos desde standard input, pero podria ser desde un archivo std::istream_iterator<std::string> ii( std::cin ); cout << "--->Entrada parseada separando por whitespace:" << endl; // Supongamos que dejamos de leer cuando leemos el string "FIN" std::vector<string> palabras; while ( *ii != "FIN" ){ cout << *ii << endl; palabras.push_back(*ii); ii++; } // Ordenamos las palabras cout <

SVN: Tagging and Branching

Spanish version / Versión en Español What are "branches" and "tags" when we're talking about SVN? A tag is simply a specially marked revision: it allows us to give a revision a friendlier name than, say, "revision 901". This is why tags are usually associated to a new release of our product. For this reason, it's common practice to create a tag each time a new version of the software is released, setting the file versions in concordance with the tag name. For instance, a normal name for a tag would be "Version 3.2.0". On the other hand, a branch is a separate line of development, and it can be used in various scenarios. Say we need to do a major refactoring without breaking our colleagues' solution, and we need to commit along the way because work will be long and complex. So we create a branch, as a copy of the "trunk" (the main development line), and work there. When we're done, we merge our changes back int

SVN: Tagging y Branching

Versión en inglés / English version ¿Qué son un Tag y un Branch de SVN? Ambos son creados inicialmente como copias del "trunk" de una carpeta SVN. Un Tag es simplemente una revisión SVN marcada especialmente, lo que nos permite darle un nombre más amigable que "revisión 901". Es por esto que es usual ir crear un tag cada vez que se publica una nueva versión del software, marcando la versión de los archivos en concordancia con el nombre del tag; un nombre esperable para un tag sería "Versión 3.2.0". Por otro lado, un branch es una línea de desarrollo separada, y se usa en varios escenarios. Supongamos que queremos hacer un gran refactoring sin interferir con el trabajo del equipo, y queremos hacer commits a lo largo de nuestro trabajo porque es largo y complejo. Por lo tanto, creamos un branch como una copia del "trunk" (la línea principal de desarrollo) y trabajamos ahí. Cuando terminamos, hacemos un merge de nuestros cambios en el tru