名前のあるタイプがたくさんあります。(これらにはより多くの機能がありますが、この説明のために名前のみが関連しています。) これらの型とその名前は、マクロを使用してコンパイル時に設定されます。
#define DEFINE_FOO(Foo_) \
struct Foo_ : public foo_base<Foo_> { \
static char const* name() {return #Foo_;} \
}
次に、型はコンパイル時のリスト (古典的な単純な再帰的なコンパイル時のリスト) に結合されます。このリストから、オブジェクトの名前を連結してリストの名前を作成する必要があります。
template<class Foo, class Tail = nil>
struct foo_list {
static std::string name_list() {return Foo::name() + "-" + Tail::name();}
};
template<class Foo>
struct foo_list<Foo,nil> {
static std::string name_list() {return Foo::name();}
};
コードはここでエラーが含まれる可能性があるところまで煮詰められていますが、実際にはこれはかなりうまく機能します。
コンパイル時に実際によく知られている型を表すかなり長い文字列を実行時に作成してコピーすることを除いて。これは、組み込みデバイスで実行されるかなりパフォーマンスに敏感なコード部分であるため、これを次のように変更したいと思います。
- リストの文字列は、理想的にはコンパイル時に作成されるか、それができない場合は実行時に作成されます。
- #1 によると、文字列はメモリに固定されているため、C 文字列へのポインターをコピーするだけで済みます。
- これは、私たちが今行き詰まっている C++03 でコンパイルされます。
これどうやってするの?
(これにより、これに使用できる汚いトリックの武器が拡大する場合:foo
オブジェクトの名前はコードによってのみ作成および読み取られ、foo_list
名前文字列のみが人間が判読できると予想されます。)