コンパイル時文字列っぽいもの
Borland C++の__emit__()擬似関数を使えば、コンパイル時にC文字列を生成できそうな気がしてやってみました。
// 文字列の実体たち __declspec(naked) void ct_string0() { __emit__('\0'); } template<char C1> __declspec(naked) void ct_string1() { __emit__(C1); __emit__('\0'); } template<char C1, char C2> __declspec(naked) void ct_string2() { __emit__(C1); __emit__(C2); __emit__('\0'); } template<char C1, char C2, char C3> __declspec(naked) void ct_string3() { __emit__(C1); __emit__(C2); __emit__(C3); __emit__('\0'); } // 怪しげなキャスト群 inline const char* ct_string() { void (*ptr)() = &ct_string0; return (const char*)ptr; } template<char C1> inline const char* ct_string() { void (*ptr)() = &ct_string1<C1>; return (const char*)ptr; } template<char C1, char C2> inline const char* ct_string() { void (*ptr)() = &ct_string2<C1,C2>; return (const char*)ptr; } template<char C1, char C2, char C3> inline const char* ct_string() { void (*ptr)() = &ct_string3<C1,C2,C3>; return (const char*)ptr; } #include <cassert> #include <iostream> int main() { // C文字列として使える std::cout << ct_string() << std::endl; std::cout << ct_string<'A'>() << std::endl; std::cout << ct_string<'A','B'>() << std::endl; std::cout << ct_string<'A','B','C'>() << std::endl; // インスタンスは1個なので、常に同じアドレスが返される assert(ct_string<'A'>() == ct_string<'A'>()); }
__declspec(naked)で関数のプロローグ/エピローグコードが付かなくなるのと、非型のテンプレート引数を__emit__()に渡せるのがミソです。
多分、Boost.Preprocessorを使えば文字列の長さを簡単に伸ばせると思います。
何の役に立つかは不明ですが。