1

私はBoostSpiritパーサーを使用していますが、パーサーが解析しているため、セマンティックアクションはクラスParserActionsのインスタンスに反映されます。

パーサーのコードは次のとおりです(関連部分)

struct urdf_grammar : public grammar<urdf_grammar> {

template <typename ScannerT>
        struct definition {

    definition(urdf_grammar const& self) {


        prog = (alpha_p >> *alnum_p)[&(self.actions.do_prog)];

    }

    rule<ScannerT> prog;

    rule<ScannerT> const&
            start() const {
        return prog;
    }
};

const ParserActions & actions;

explicit urdf_grammar(const ParserActions & actions = ParserActions()) : actions(actions) {
}  
};
4

3 に答える 3

3

メンバー変数または関数のアドレスを取得するには、次を使用します。

&MyClass::MyMember

メンバー関数ポインタを呼び出すには、次のいずれかを使用します。

(my_class.*ptr_to_member)( /* arguments */ )
(my_ptr->*ptr_to_member)( /* arguments */ )

詳細についてGoogleで見つけたランダムリンク:http ://www.goingware.com/tips/member-pointers.html

于 2010-03-04T13:08:52.470 に答える
3

オブジェクトのメンバー関数を呼び出すには、次の2つを提供する必要があります。

  1. 前に述べたように、メンバー関数のアドレスは、次のように記述して取得できます。&my_class::my_member
  2. メンバー関数を呼び出すオブジェクトのインスタンスへのポインター(または参照)

スピリットセマンティックアクションは、特定のインターフェイスを公開する関数または関数オブジェクトを提供することを期待します。あなたの場合、期待されるインターフェースは次のとおりです。

void func(Iterator first, Iterator Last);

ここで、Iteratorは、解析関数を呼び出すために使用されるイテレータータイプです(からアクセス可能typename ScannerT::iterator_t)。あなたがする必要があるのは、メンバー関数を呼び出しながら、言及されたインターフェースを公開する関数オブジェクトを作成することです。これは手動で行うことができますが、それを行うのはせいぜい面倒です。関数オブジェクトを作成する最も簡単な方法は、Boost.Bindを使用することです。

prog = (alpha_p >> *alnum_p)
       [
           boost::bind(&ParserActions::do_prog, self.action)
       ];

これにより、必要な関数オブジェクトが作成され、メンバー関数がバインドおよびラップされます。

これはすべて、メンバー関数が引数を取らないことを前提としています。イテレータのペアを渡す必要がある場合は、セマンティックアクションが関数に対して呼び出され、コンストラクトは次のように記述する必要があります。

prog = (alpha_p >> *alnum_p)
       [
           boost::bind(&ParserActions::do_prog, self.action, _1, _2)
       ];

1番目と2番目のパラメーターをバインドされた関数に転送するように関数オブジェクトに指示します。

于 2010-03-04T14:23:33.727 に答える
1

関数ポインターとメンバー関数ポインターには基本的な違いがあります。

  • 関数ポインタは、正しい型の引数を使用して呼び出す必要があります。

  • メンバー関数ポインタは、正しいタイプのオブジェクトと正しいタイプの引数を使用して呼び出す必要があります。

オブジェクトから行うようにメンバー関数ポインターを作成しても、オブジェクトはポインターに登録されません。

そのようなことをしたい場合は、そうしているさまざまなライブラリがあります(ブーストタグがあります。そのような例については、バインドとシグナルを参照してください)。

于 2010-03-04T13:31:54.210 に答える