|
いずれ困ったりするときの役に立てばいいかな程度の雑記です 実際に動かすのがたぶん一番です。 プリプロセッサ応用編 #define なんとか #include <ファイル名> のように#が先頭に付いている奴ら 使い方次第ではなんかいろいろ化けそうな奴らです #define A Aを定義する #define A B AをBと定義する #define Add(x,y) ((x) + (y)) 変数に()を忘れると展開がおかしくなるので注意 #define X(A) #A 変数(関数、クラス)名に展開 #define X(A) str##A str(文字列)にAの変数(関数、クラス)名を連結させることができます。 #undef A Aの定義を無効にする。#undefの行で無効になる #ifdef A (Aが定義されていたら行う宣言or処理) #else (Aが定義されていなかったら行う宣言or処理) #endif Aが#defineされていたら分岐を行う #ifndef A (Aが定義されていなかったら行う宣言or処理) #else (Aが定義されていたら行う宣言or処理) #endif #ifdefの逆、ヘッダーの多重インクルード防止によく使う #include ファイル名 でファイルの内容を展開 今回はプリプロセッサを使って遊んでみる。 とりあえずファイルふたつ用意 //Fruits.txt X(Apple) X(Grape) X(Banana) //main.cpp
#include <iostream>
using namespace std;
#define X(A) A,
enum{
#include "Fruits.txt"
};
#undef X
#define X(A) #A,
const char *Fstr[]={
#include "Fruits.txt"
};
#undef X
// 関数
void Func_Apple(){cout << "This is Apple" << endl;};
void Func_Grape(){cout << "This is Grape" << endl;};
void Func_Banana(){cout << "This is Banana" << endl;};
#define X(A) Func_##A,
void (*func[])() = {
#include "Fruits.txt"
};
#undef X
class Fruits
{
public:
virtual void Out(){}
};
class CApple: public Fruits {public: virtual void Out(){cout << "An Apple" << endl;}};
class CGrape: public Fruits {public: virtual void Out(){cout << "An Grape" << endl;}};
class CBanana: public Fruits {public: virtual void Out(){cout << "An Banana" << endl;}};
template <class T>
Fruits *createFruits(){ return new T;}
#define X(A) createFruits<C##A>,
Fruits *(*create[])() = {
#include "Fruits.txt"
};
#undef X
int main() {
#define strgen1(x) "x"
#define strgen2(x) x
#define strgen3(x) #x
char *p, *str = "abc";
p = strgen1(str); /* p = "x" */
cout << p << endl;
p = strgen2(str); /* p = "abc" */
cout << p << endl;
p = strgen3(str); /* p = "str" */
cout << p << endl;
#define symadd(x, y) sym##x + sym##y
int sym1 = 3, sym2 = 5;
int i = symadd(1, 2); /* sym1 + sym2 */
cout << i << endl;
cout << Apple << endl;
cout << Grape << endl;
cout << Banana << endl;
cout << Fstr[Apple] << endl;
cout << Fstr[Grape] << endl;
cout << Fstr[Banana] << endl;
func[Apple]();
func[Grape]();
func[Banana]();
Fruits *fruits1 = create[Apple]();
Fruits *fruits2 = create[Grape]();
Fruits *fruits3 = create[Banana]();
fruits1->Out();
fruits2->Out();
fruits3->Out();
delete fruits1;
delete fruits2;
delete fruits3;
return 0;
}
#define X #undef X 列挙体を添え字でわたせば、 |