test-has_member_xxx.cpp
Boost.MPLにはhas_xxxという、クラスが特定のメンバ型を持つか
判定するメタ関数(を定義するマクロ)があります。
使い方や実装テクニックは、↓で詳しく解説されています。
http://cpplover.blogspot.com/2008/10/hasxxx.html
上記ブログでは、型だけでなくメンバ変数やメンバ関数にも
対応したhas_xxxの作り方も記されています。すごいです。
しかしサンプルコードのつもりで書かれたためでしょう、
もっと汎用的に書けるな、とも思いました。
メンバのシグネチャを渡すようにして、特定の名前とシグネチャの
メンバが存在するか判定するようにしたのが、
sprig::has_member_xxxメタ関数です。
- test-has_member_xxx.cpp
#include <utility> #include <string> #include <sprig/type_traits/has_member_xxx.hpp> #include <sprig/cindent.hpp> // has_member_firstを定義 SPRIG_HAS_MEMBER_XXX_TRAIT_DEF(first); // has_member_c_strを定義 SPRIG_HAS_MEMBER_XXX_TRAIT_DEF(c_str); int main(int argc, char* argv[]) { sprig::csection cs("test-has_member_xxx"); sprig::cout_section_comment("int型のfirstメンバ変数を持つか?"); sprig::cout_section_line( "test", has_member_first<std::pair<int, int>, int std::pair<int, int>::*>::value ); sprig::cout_section_comment("double型のfirstメンバ変数を持つか?"); sprig::cout_section_line( "test", has_member_first<std::pair<int, int>, double std::pair<int, int>::*>::value ); sprig::cout_section_comment("const修飾された、c_str()メンバ関数を持つか?"); sprig::cout_section_line( "test", has_member_c_str<std::string, char const* (std::string::*)() const>::value ); sprig::cout_section_comment("const修飾されていない、c_str()メンバ関数を持つか?"); sprig::cout_section_line( "test", has_member_c_str<std::string, char const* (std::string::*)()>::value ); return 0; }
- 実行結果
<test-has_member_xxx> <!-- int型のfirstメンバ変数を持つか? --> <test>1</test> <!-- double型のfirstメンバ変数を持つか? --> <test>0</test> <!-- const修飾された、c_str()メンバ関数を持つか? --> <test>1</test> <!-- const修飾されていない、c_str()メンバ関数を持つか? --> <test>0</test> </test-has_member_xxx>
今さら思ったけどSprig.Cindentの
XML風フォーマットは実は結構読みづらいかもしれない。