Develop and Download Open Source Software

View Borland C++ Compiler 5.82で動かすときの注意

category(Tag) tree

file info

category(Tag)
root
file name
BCC582
last update
2009-01-16 13:37
type
Plain Text
editor
しまたろ
description
Borland C++ Compiler 5.82で動かすときの注意
language
Japanese
translate
Mercury::Regexは、Borland C++ Compiler 5.82(以下BCC)でも動作を確認しています。
ただし、このバージョンのBCCは少しクセがあるので、使用するときは少し注意が必要です。

たとえば、以下のコードがあったとしましょう。
------------------------------------------------------------
	const char pattern[] = "<[^>]+>";
	const char text   [] = "<strong>";
	mercury::regex::MATCH_INFO<const char *> match_info;

	const mercury::regex re(pattern);
	if(re.match(text, match_info))
	{
		// マッチした
	}
------------------------------------------------------------
このコードは、Microsoft Visual C++ 2003 Professiona Edition, 2008 Express Edition, GNU G++ 3.4.5 on MinGWではコンパイルが通ります。
しかし、BCCではmatch()の行をコンパイルするとき、以下のどちらをコンパイルするべきかわからないというエラーメッセージ"E2015"を出します。

template<                     typename _MATCH_INFO> bool match(const char *      , _MATCH_INFO &)
template<typename _Container, typename _MATCH_INFO> bool match(const _Container &, _MATCH_INFO &)

こちらとしては前者を選んでほしいのですが、どうやらBCCは文字列を"const char *"として前者を選ぶべきか、"const char[9]"として後者を選ぶべきか判断できないようです([9]というのはtextのサイズです)。
これを回避するには、以下のいずれかで記述してください。

1. 配列ではなくポインタを使う
------------------------------------------------------------
	const char *pattern = "<[^>]+>";
	const char *text    = "<strong>";
	mercury::regex::MATCH_INFO<const char *> match_info;

	const mercury::regex re(pattern);
	if(re.match(text, match_info))
	{
		// マッチした
	}
------------------------------------------------------------

2. 配列を使い、match()に渡すときにポインタに変換する
------------------------------------------------------------
	const char pattern[] = "<[^>]+>";
	const char text   [] = "<strong>";
	mercury::regex::MATCH_INFO<const char *> match_info;

	const mercury::regex re(pattern);
	if(re.match(&text[0], match_info))
	{
		// マッチした
	}
------------------------------------------------------------

3. 強制的に match(const char *, _MATCH_INFO &)だと認識させる
------------------------------------------------------------
	const char pattern[] = "<[^>]+>";
	const char text   [] = "<strong>";
	mercury::regex::MATCH_INFO<const char *> match_info;

	const mercury::regex re(pattern);
	if(re.match<mercury::regex::MATCH_INFO<const char *> >(text, match_info))
	{
		// マッチした
	}
------------------------------------------------------------

4. 配列やポインタをやめて、std::string等のコンテナを使う
------------------------------------------------------------
	const std::string pattern = "<[^>]+>";
	const std::string text    = "<strong>";
	mercury::regex::MATCH_INFO<std::string::const_iterator> match_info;

	const mercury::regex re(pattern);
	if(re.match(text, match_info))
	{
		// マッチした
	}
------------------------------------------------------------

必ずしも配列である必要のない場合はポインタを渡し、配列でなければならない場合はポインタに変換するとよいでしょう。また、変数を媒介することなく直接match()にパターンをリテラルとして渡す場合は強制的に認識させるしかありません。
もちろん、最も現代的な解決法はstd::stringを使うことですが、簡単にはいかない事情もあるでしょう。

"const _Container &"を参照渡しでなく値渡しにすれば大丈夫なんですが、それだとパフォーマンスの問題が出ます。このオーバーロード関数自体をなくしてしまうという方法もあるんですけどね。

Boost.Regex++がなぜコンテナ全般を引数に取らないか、その理由がわかったような気がします。