Katakanlah kita akan mengabaikan hal-hal yang jelas seperti pelindung tajuk.
Terkadang, Anda ingin membuat kode yang perlu disalin / ditempelkan oleh precompiler:
#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)
yang memungkinkan Anda untuk kode ini:
RAISE_ERROR_STL("Hello... The following values " << i << " and " << j << " are wrong") ;
Dan dapat menghasilkan pesan seperti:
Error Raised:
====================================
File : MyFile.cpp, line 225
Function : MyFunction(int, double)
Message : "Hello... The following values 23 and 12 are wrong"
Perhatikan bahwa mencampur template dengan makro dapat menghasilkan hasil yang lebih baik (yaitu secara otomatis menghasilkan nilai-nilai berdampingan dengan nama variabel mereka)
Di lain waktu, Anda memerlukan __FILE__ dan / atau __LINE__ dari beberapa kode, untuk menghasilkan info debug, misalnya. Berikut ini adalah klasik untuk Visual C ++:
#define WRNG_PRIVATE_STR2(z) #z
#define WRNG_PRIVATE_STR1(x) WRNG_PRIVATE_STR2(x)
#define WRNG __FILE__ "("WRNG_PRIVATE_STR1(__LINE__)") : ------------ : "
Seperti dengan kode berikut:
#pragma message(WRNG "Hello World")
itu menghasilkan pesan seperti:
C:\my_project\my_cpp_file.cpp (225) : ------------ Hello World
Di lain waktu, Anda perlu membuat kode menggunakan operator gabungan # dan ##, seperti menghasilkan getter dan setter untuk properti (ini untuk kasus yang cukup terbatas, sampai).
Di lain waktu, Anda akan menghasilkan kode yang tidak dapat dikompilasi jika digunakan melalui fungsi, seperti:
#define MY_TRY try{
#define MY_CATCH } catch(...) {
#define MY_END_TRY }
Yang bisa digunakan sebagai
MY_TRY
doSomethingDangerous() ;
MY_CATCH
tryToRecoverEvenWithoutMeaningfullInfo() ;
damnThoseMacros() ;
MY_END_TRY
(masih, saya hanya melihat kode semacam ini benar digunakan sekali )
Terakhir, namun tidak kalah pentingnya, yang terkenal 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;
}
(Catatan: kode salin / tempel dari beranda boost)
Yang (IMHO) jauh lebih baik daripada std::for_each
.
Jadi, makro selalu berguna karena mereka berada di luar aturan kompiler normal. Tapi saya menemukan bahwa sebagian besar waktu saya melihat satu, mereka secara efektif tetap kode C tidak pernah diterjemahkan ke dalam C ++ yang tepat.