ボレロ村上 - ENiyGmaA Code

中3女子です。

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風フォーマットは実は結構読みづらいかもしれない。