2010-03-04 121 views
1

我正在使用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) { 
} 
}; 
+0

你能給出行動的結構/ do_expession是如何定義的? – 2010-03-04 13:08:17

+0

你能否澄清boost-spirit標籤? – Francesco 2010-03-04 13:08:56

+2

如果您發佈更多代碼(例如,來自函數f1)以及編譯器提供的確切錯誤消息,則可能會得到更好的答案。 – AshleysBrain 2010-03-04 13:11:10

回答

3

爲了叫你需要提供兩樣東西的對象的成員函數:

  1. 成員函數的地址,因爲之前說過你可以通過寫&my_class::my_member
  2. 指針(或引用)到要調用成員函數的對象的實例

Spirit語義操作期望您提供暴露特定接口的函數或函數對象。在你的情況下,預期的接口是:

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

指示函數對象在其第一和第二個參數轉發給綁定功能。

+0

謝謝,我仍然遇到一些問題。根據http://www.boost.org/doc/libs/1_42_0,'self'不應該是self.actions而是參數的順序改爲boost :: bind(&ParserActions :: do_prog,self,_1,_2) /libs/bind/bind.html#with_member_pointers – myahya 2010-03-04 15:38:28

+1

是的,你是對的。我從頭開始寫上述...... – hkaiser 2010-03-04 17:30:07

+0

我在上面的答案中修復了代碼,以反映正確的語法。 – hkaiser 2010-03-04 17:43:56

3

要拍攝成員變量或函數的地址,使用:

&MyClass::MyMember 

要調用一個成員函數指針,使用一個:

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

隨機鏈接我在谷歌找到了更多的信息:http://www.goingware.com/tips/member-pointers.html

1

有函數指針和成員函數指針之間的根本區別:

  • 一個函數指針必須按正確的類型的參數被調用,

  • 一個成員函數指針必須被稱爲正確類型的對象和正確類型的參數。

像你從一個對象那樣構建一個成員函數指針不會在指針中註冊該對象。

如果你想要這樣的事情,有各種各樣的庫這樣做(你有一個提升標籤,看到綁定和信號的例子)。