TJSのVC++でのコンパイル
2005年7月9日前回のサンプルでは正規表現のtjsRegExp.cppがどうしてもコンパイルが通らなかった。楓softwareの井元さんの助言で、とりあえず何が悪いのかが漠然と見えてきた。
まずはソースコードのおさらいからしてみる。
tjsRegExp.cppのtTJSReplacePredicatorクラスのコンストラクタ中で同クラス中のCallbackメソッドを関数オブジェクトとして利用しようとしている。
また、同じソースコードのtTJSSplitPredicatorクラスも同様のことをやろうとしている。
ここで、一つの問題が発生する。mem_funが適用できない。
本来mem_funでメンバ関数アダプタを適用できるのはthiscall関数のみであるのに、TJS_cdeclマクロ(その実体は__cdecl)でC関数の呼び出し規約をCallbackメソッドに適用しようとしている。なぜだかわからない(bccではこれは仕様なのだろうか?)。
これを外すことでmem_funは適用できるようになる。
さて、ここまでは井元さんの日記のおさらいである。
ここから先は、自分でなんとか解決を図ってみた。
次に直面したのは、bind1stが重複しているという問題である。
tjsRegExp.cppではstd::bind1stが使用されている。これを用いると、Microsoftのfunctionalヘッダファイルで定義が重複するとコンパイラに怒られる。
さて、では何と重複しているのだろう?GrepでVisualC++のインクルードディレクトリにbind1stで検索をかける。ここで、注目に値する二つの検索結果が得られた。
1つは、boost/functional.hpp中、boost名前空間中のbind1st
2つ目は、Microsoftのfunctionalヘッダファイル中、std名前空間中のbind1st
この二つが存在しているのだ。しかも、boost/functional.hpp中ではMicrosoftのfunctionalヘッダを読み込んでいる。で、これから何がわかるかというと、boostを利用する際は、関数オブジェクトへの値のバインドは、boost::bind1stを使えということらしい。boost::bind1stに使える関数ポインタアダプタはboost::mem_refということもこのヘッダからわかった。
で、結局最終的には次のようにソースコードを書き直すことで解決した。
unsigned int match_count = regex_grep (
boost::bind1st(boost::mem_fun(&tTJSReplacePredicator::Callback),this),
target.c_str (),
_this->RegEx,
match_default|match_not_dot_null) ;
長かった。とりあえず、井元さんに報告しよう。
まずはソースコードのおさらいからしてみる。
tjsRegExp.cppのtTJSReplacePredicatorクラスのコンストラクタ中で同クラス中のCallbackメソッドを関数オブジェクトとして利用しようとしている。
また、同じソースコードのtTJSSplitPredicatorクラスも同様のことをやろうとしている。
ここで、一つの問題が発生する。mem_funが適用できない。
本来mem_funでメンバ関数アダプタを適用できるのはthiscall関数のみであるのに、TJS_cdeclマクロ(その実体は__cdecl)でC関数の呼び出し規約をCallbackメソッドに適用しようとしている。なぜだかわからない(bccではこれは仕様なのだろうか?)。
これを外すことでmem_funは適用できるようになる。
さて、ここまでは井元さんの日記のおさらいである。
ここから先は、自分でなんとか解決を図ってみた。
次に直面したのは、bind1stが重複しているという問題である。
tjsRegExp.cppではstd::bind1stが使用されている。これを用いると、Microsoftのfunctionalヘッダファイルで定義が重複するとコンパイラに怒られる。
さて、では何と重複しているのだろう?GrepでVisualC++のインクルードディレクトリにbind1stで検索をかける。ここで、注目に値する二つの検索結果が得られた。
1つは、boost/functional.hpp中、boost名前空間中のbind1st
2つ目は、Microsoftのfunctionalヘッダファイル中、std名前空間中のbind1st
この二つが存在しているのだ。しかも、boost/functional.hpp中ではMicrosoftのfunctionalヘッダを読み込んでいる。で、これから何がわかるかというと、boostを利用する際は、関数オブジェクトへの値のバインドは、boost::bind1stを使えということらしい。boost::bind1stに使える関数ポインタアダプタはboost::mem_refということもこのヘッダからわかった。
で、結局最終的には次のようにソースコードを書き直すことで解決した。
unsigned int match_count = regex_grep (
boost::bind1st(boost::mem_fun(&tTJSReplacePredicator::Callback),this),
target.c_str (),
_this->RegEx,
match_default|match_not_dot_null) ;
長かった。とりあえず、井元さんに報告しよう。
コメント