例えば以下のソースコードがある。
#include<boost/xpressive/xpressive.hpp>
int main()
{
boost::xpressive::sregex hoge = "test" << boost::xpressive::_;
}
自明にダメなコードだが気づかなかったものとしてこれでビルドしてみる。
するとエラー一覧には以下の様なコンパイルエラーが出るはず。
error C2664: 'int boost::mpl::assertion_failed<false>(boost::mpl::assert<false>::type)' : 引数1を'boost::mpl::failed************boost::xpressive::INVALID_REGULAR_EXPRESSION::* ***********'から'boost::mpl::assert<false>::type'へ変換できません。
非常につらい気持ちになる。何よりこのエラーの場所がbasic_regex.hppの117行目と出るのだから頭を抱える。
こういうtemplate特有の意味不明を極めたコンパイルエラーは非常につらみがあるのだがこういう時とりあえず出力を見てみる。
1>------ ビルド開始: プロジェクト:boost_test, 構成:Release Win32 ------
1> main.cpp
1>C:\boost_1_55_0_32_bin\boost/xpressive/basic_regex.hpp(117): error C2664: 'int boost::mpl::assertion_failed<false>(boost::mpl::assert<false>::type)' : 引数 1 を 'boost::mpl::failed ************boost::xpressive::INVALID_REGULAR_EXPRESSION::* ***********' から 'boost::mpl::assert<false>::type' へ変換できません。
1> コンストラクターはソース型を持てません、またはコンストラクターのオーバーロードの解決があいまいです。
1> main.cpp(5) : コンパイルされたクラスの テンプレート のインスタンス化 'boost::xpressive::basic_regex<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>::basic_regex<boost::proto::exprns_::expr<Tag,Args,2>>(const Expr &)' の参照を確認してください
1> with
1> [
1> Tag=boost::proto::tagns_::tag::shift_left
1> , Args=boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[5]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::xpressive::detail::any_matcher>,0> &>
1> , Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[5]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::xpressive::detail::any_matcher>,0> &>,2>
1> ]
1> main.cpp(5) : コンパイルされたクラスの テンプレート のインスタンス化 'boost::xpressive::basic_regex<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>::basic_regex<boost::proto::exprns_::expr<Tag,Args,2>>(const Expr &)' の参照を確認してください
1> with
1> [
1> Tag=boost::proto::tagns_::tag::shift_left
1> , Args=boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[5]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::xpressive::detail::any_matcher>,0> &>
1> , Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[5]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::xpressive::detail::any_matcher>,0> &>,2>
1> ]
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
もっとつらい気持ちになるが、とりあえず上から見ていく。
標準ライブラリやboostにバグはないものとして(いやある可能性はあるのだがそれは置いておく)見ていくと次の文に目が止まるはず。
1> main.cpp(5) : コンパイルされたクラスの テンプレート のインスタンス化 'boost::xpressive::basic_regex<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>::basic_regex<boost::proto::exprns_::expr<Tag,Args,2>>(const Expr &)' の参照を確認してください
とりあえずmain.cpp(5)をチェックする。するとビットシフトの向きが逆になっていることに気づくはず。いやさすがにその場で気づかなくてもboostjpでのboost.xpressiveの使い方をチェックすればわかるはず。
今回の教訓。
boost.xpressiveのシフト演算子の向きは間違えないようにしようtemplate絡みのコンパイルエラーは出力を確認しよう。
PR