Contenu connexe
Similaire à Define and expansion of cpp macro
Similaire à Define and expansion of cpp macro (20)
Define and expansion of cpp macro
- 7. 10個の連番の関数を宣言する例
● #define F(z, i, d)
void BOOST_PP_CAT(f, i)(int);
BOOST_PP_REPEAT(10, F, ~)
→ void f0(int); void f1(int); …… void f9(int);
● 実際に void f0(int); … とかいうのがソースに書か
れている,と扱われる
- 9. Scope Exit の簡単な実装
#define SCOPE_EXIT
scope_exit_t BOOST_PP_CAT(scope_exit_var, __LINE__) = [&]
struct scope_exit_t {
std::function<void()> f;
template<typename F>
scope_exit_t(F f) : f(f) {}
~scope_exit_t() { f(); }
};
int main() {
SCOPE_EXIT { std::cout << "hogen"; };
SCOPE_EXIT { std::cout << "fuga, "; };
}
→ fuga, hoge
- 10. Scope Exit の簡単な実装
● RAIIで必要な処理をさせるためにはそれ用の変数
もしくはクラスに名前を付ける必要がある
● しかし単にデストラクタを呼ぶだけなので,人間側
の都合としてはどうでもよい
●
そんなわけでこういうマクロを書けば余計な名前を
考える手間もコード上のノイズも減る
- 25. 評価順の制御
● #define CAT(a, b) a ## b
CAT(A, CAT(B, C))
→ACAT(B, C)
● 外側のマクロを置き換えると A ## CAT(B, C)
● 連結すると ACAT(B, C) なので引数としては扱わ
れなくなる
- 26. 評価順の制御
● #define CAT(a, b) CAT_I(a, b)
#define CAT_I(a, b) a ## b
ーCAT(A, CAT(B, C))
→ABC
● 外側のマクロを置き換えると CAT_I(A, CAT(B, C))
●
トークン連結はないのでそのまま
● 引数について展開する(CATが意図通り動くとする)と CAT_I(A, BC)
●
元の場所に戻してそこからもう一度置換する
● 外側のマクロを置き換えると A ## BC
● 連結して ABC
●
以下省略
- 27. 引数の解体
● #define REM(...) __VA_ARGS__
#define AP(f, x) f(42, x)
#define F(n, x) F_I(n, REM x)
#define F_I(n, x) F_II(n, x)
#define F(n, x, y, z)
AP(F, (A, B, C))
→
● カッコで包めば一つの引数にできるので,任意長
のarityのマクロを固定長引数のマクロの中で扱え
る
● このマクロの置換がどのように行われるかは自明
なので,手順は読者の課題とする(放棄)
- 30. 分岐
● 分岐は基本的な技法だけで書ける
● #define IF(c, t, f) CAT(IF, c)(t, f)
#define IF1(t, f) t
#define IF0(t, f) f
IF(1, hoge, fuga)
→hoge
IF(0, hoge, fuga)
→fuga
- 35. 繰り返し
●
最も単純な実装
● #define REPEAT(n, m) REPEAT ## n(m)
#define REPEAT0(m)
#define REPEAT1(m) m(0)
#define REPEAT2(m) REPEAT1(m) m(1)
#define REPEAT3(m) REPEAT2(m) m(2)
#define F(n) hoge ## n
REPEAT(3, F)
→hoge0 hoge1 hoge2
● mを関数マクロとみなすことで,繰り返す内容を自由に指定で
きる
- 36. 繰り返し
●
もっと複雑なもの
● #define WHILE WHILE0
#define WHILE_END(p, st, op) st
#define WHILE0(p, st, op)
IF(p(st), WHILE1, WHILE_END)(p, st, op)
#define WHILE1(p, st, op)
IF(p(op(st)), WHILE2, WHILE_END)(p, op(st), op)
#define WHILE2(p, st, op)
IF(p(op(st)), WHILE3, WHILE_END)(p, op(st), op)
#define WHILE3(p, st, op)
IF(p(op(st)), WHILE4, WHILE_END)(p, op(st), op)
…
● p(st)が偽だったらst
● 真だったらop(st)した結果で同じことを繰り返す
- 42. Tuple
● (a, b, c) のような形式をtupleという
● 長さを変更できないが要素へのアクセスはO(1)な
データ構造
– だった
● C++11からVariadic Macroが導入されたので長さ
の制限がなくなった