Help us understand the problem. What is going on with this article?

boost.diのannotations `BOOST_DI_INJECT(Hoge , (named = int1) int a, double b)` みたいな文法ってどういう原理なの?

※boost.diそのものに関する話は出てきません。ご了承ください
この記事は 2019C++アドベントカレンダー (https://qiita.com/advent-calendar/2019/cpp) 5日目の記事になります

boost.diのannotations

boost.diには(今気にすべきことだけを言うと)「オブジェクトの構築を補助する機能」が含まれている
その中にはannotationsというものがあり、以下のようにコンストラクタ引数に名前を付ける機能がある

// 名前用型
auto int1 = [] {};
// 型定義
struct Hoge {
  BOOST_DI_INJECT(Hoge , (named = int1) int a, double b) // aに"int1"という名前を付ける
     : a(a), b(b) {}
  int a = 0;
  double b = 0;
};
auto injector = di::make_injector(
    di::bind<int>().named(int1).to(42)  //intでint1という名前のパラメタを42で初期化
    , di::bind<double>().to(3.14)  // doubleのパラメタを3.14で初期化
);
auto x = injector.create<Hoge>(); // 便利に構築。何が便利なのかはboost.diのドキュメントかDIに関する記事を読んでくれ 

// 想定通りにオブジェクトが構築された
std::cout<<x.a<<std::endl;  // 42
std::cout<<x.b<<std::endl;  // 3.14

https://wandbox.org/permlink/CvgqL0NBjJEcRtPr

しかし、BOOST_DI_INJECT(Hoge , (named = int1) int a, double b)(named = int1) int aという文法はC++的に考えて奇妙だ。しかもこのannotations、付けてもつけなくてもよい
これはどういったトリックだろうか?

大雑把な実装原理

#define B(_) A
#define TEST(X) B X

上のようなマクロを書いたとき、TEST(X)X

  • (hoge) 1 の場合: B(_)で置換されてtoken列 A 1 になる
  • 1の場合: それ以上置換できるルールが存在しないのでtoken列 B 1になる

ことを利用している

もう少し具体的な挙動

#define PP_CAT(L,R) PP_CAT2(L,R)
#define PP_CAT2(L,R) L##R
#define AA 1,
#define AB 0,
#define B(_) A
#define TEST(X) PP_CAT(A,B X)
  • TEST((1)1)
    • TEST((1)1) -> PP_CAT(A,B(1)1) -> PP_CAT2(A,A 1) -> AA 1 -> 1,1 のように置換される
  • TEST(1)
    • TEST(1) -> PP_CAT(A,B 1) -> PP_CAT2(A,B 1) -> AB 1 -> 0,1 のように置換される

このように置換すれば最終的にいい感じのtoken列に変換できるので、あとはマクロなりで好きな個所を取り出しいい感じに使える using type = なんとか でもなんでも生やしてほしい

https://wandbox.org/permlink/HYQfxPdQiKjErjbv

boost.diにおける実装

https://github.com/boost-experimental/di/blob/v1.1.0/include/boost/di/aux_/preprocessor.hpp#L102
この行のあたりの挙動を追ってほしい

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away