楓の掲示板

タイトル 解決しました。
投稿日: 2005/07/10(Sun) 04:25
投稿者きらら   <ac17805w@st.nagaoka-ct.ac.jp>
参照先http://ilaliart.sourceforge.jp

井元さん。

こんばんは、きららです。

> > まずお聞きしたいのですが、Visual Studioのバージョン、Boostのバージョン、STLPortのバージョン(使っていれば)はなんでしょうか?

Visual Studio -> .Net 2003
Boost -> 1.32
STLPort -> 未使用

です。特にboostに関しては、BOOST_REGEX_NO_LIBを定義して~/boost<ver>/libs/regex/src/の内容をプロジェクトに追加してソースコードを直接コンパイルするようにしていました(これはboostが何か悪さをしているのではないかと色々やってみた結果だったのですが、あまり意味はありませんでした)。

まずはソースコードのおさらいからしてみます。
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) ;

最終的な結論としては、boostを使う場合は、using namespace std;は同時に利用しないほうが良いようです。boostではboostのアダプタ、バインダを利用するのが正しい使い方のようですね。

ソースコードを以下のURLにおいておきます。まだ正規表現がきちっと動くかどうかはチェックしていませんが、時間ができ次第やるつもりです。

http://ilaliart.sourceforge.jp/arc/tjstest2.zip


また、井元さんが日記で仰っていたTJS_Wマクロの問題ですが、VC++ではL##Xを用いることができる文字列は、単体だけのようです。従って次のようなコードはエラーになります。

L("Test" "Test") <- エラー
L("Test") L("Test") <- 正しい

お騒がせして申し訳ないです。大変役に立つ御助言ありがとうございました。今後とも、よろしくお願いします。

それでは。


- 関連一覧ツリー (▼ をクリックするとツリー全体を一括表示します)

- 返信フォーム (この記事に返信する場合は下記フォームから投稿して下さい)
おなまえ
Eメール
タイトル
メッセージ   手動改行 強制改行 図表モード
参照先
reCAPTCHA
下に表示されている二つの英単語を、スペースで区切って入力してください。

暗証キー (英数字で8文字以内)

- 以下のフォームから自分の投稿記事を修正・削除することができます -
処理 記事No 暗証キー