Nehmen wir an, wir ignorieren offensichtliche Dinge wie Header Guards.
Manchmal möchten Sie Code generieren, der vom Precompiler kopiert / eingefügt werden muss:
#define RAISE_ERROR_STL(p_strMessage) \
do \
{ \
try \
{ \
std::tstringstream strBuffer ; \
strBuffer << p_strMessage ; \
strMessage = strBuffer.str() ; \
raiseSomeAlert(__FILE__, __FUNCSIG__, __LINE__, strBuffer.str().c_str()) \
} \
catch(...){} \
{ \
} \
} \
while(false)
Damit können Sie Folgendes codieren:
RAISE_ERROR_STL("Hello... The following values " << i << " and " << j << " are wrong") ;
Und kann Nachrichten generieren wie:
Error Raised:
====================================
File : MyFile.cpp, line 225
Function : MyFunction(int, double)
Message : "Hello... The following values 23 and 12 are wrong"
Beachten Sie, dass das Mischen von Vorlagen mit Makros zu noch besseren Ergebnissen führen kann (dh die Werte werden automatisch neben ihren Variablennamen generiert).
In anderen Fällen benötigen Sie die __FILE__ und / oder die __LINE__ eines Codes, um beispielsweise Debug-Informationen zu generieren. Das Folgende ist ein Klassiker für Visual C ++:
#define WRNG_PRIVATE_STR2(z) #z
#define WRNG_PRIVATE_STR1(x) WRNG_PRIVATE_STR2(x)
#define WRNG __FILE__ "("WRNG_PRIVATE_STR1(__LINE__)") : ------------ : "
Wie beim folgenden Code:
#pragma message(WRNG "Hello World")
Es generiert Nachrichten wie:
C:\my_project\my_cpp_file.cpp (225) : ------------ Hello World
In anderen Fällen müssen Sie Code mit den Verkettungsoperatoren # und ## generieren, z. B. Getter und Setter für eine Eigenschaft generieren (dies gilt nur für sehr begrenzte Fälle).
In anderen Fällen generieren Sie Code, der bei Verwendung über eine Funktion nicht kompiliert werden kann, z.
#define MY_TRY try{
#define MY_CATCH } catch(...) {
#define MY_END_TRY }
Welches kann als verwendet werden
MY_TRY
doSomethingDangerous() ;
MY_CATCH
tryToRecoverEvenWithoutMeaningfullInfo() ;
damnThoseMacros() ;
MY_END_TRY
(Trotzdem habe ich diese Art von Code nur einmal richtig gesehen )
Zu guter Letzt das berühmte boost::foreach
!!!
#include <string>
#include <iostream>
#include <boost/foreach.hpp>
int main()
{
std::string hello( "Hello, world!" );
BOOST_FOREACH( char ch, hello )
{
std::cout << ch;
}
return 0;
}
(Hinweis: Code kopieren / von der Boost-Homepage einfügen)
Welches ist (IMHO) viel besser als std::for_each
.
Makros sind also immer nützlich, da sie außerhalb der normalen Compilerregeln liegen. Aber ich finde, dass die meiste Zeit, die ich sehe, tatsächlich Reste von C-Code sind, der nie in richtiges C ++ übersetzt wurde.