Указатель на ученика - PullRequest
       8

Указатель на ученика

1 голос
/ 04 марта 2010

Я использую анализатор Boost Spirit, и, поскольку анализатор выполняет синтаксический анализ, семантические действия отражаются в экземпляре класса 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) {
}  
};

Ответы [ 3 ]

3 голосов
/ 04 марта 2010

Чтобы вызвать функцию-член объекта, вам нужно предоставить две вещи:

  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)
       ];

дает указание объекту функции переслать свой первый и второй параметр в связанную функцию.

3 голосов
/ 04 марта 2010

Чтобы получить адрес переменной-члена или функции, используйте:

&MyClass::MyMember

Чтобы вызвать указатель на функцию-член, используйте одно из:

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

Случайная ссылка, которую я нашел в Google с дополнительной информацией: http://www.goingware.com/tips/member-pointers.html

1 голос
/ 04 марта 2010

Существует принципиальное различие между указателями на функции и указателями на функции-члены:

  • указатель функции должен вызываться с аргументами правильных типов,

  • указатель на функцию-член должен вызываться с объектом правильного типа и аргументами правильных типов.

Создание указателя на функцию-член, как вы делаете из объекта, не регистрирует объект в указателе.

Если вам нужна такая вещь, то есть различные библиотеки, которые делают это (у вас есть тег повышения, см. Bind и сигналы для примеров такого).

...