1

--編集-質問を解決しました:最後のサイドノートへのコメントが役に立ちます。また、phoenix :: bindオーバーロード処理に関するコメントも役立ちます(私の答えでは)。

私は厳密な型指定要件のあるシステムで作業しています。int32_tとint64_tの制約を満たす整数を解析していることを確認したいのですが、解析された文字列を合成して上記の型に制約するパーサーは必要ありません。

これについてはどうすればよいですか?ドキュメントにはlong_long、64ビットをサポートするプラットフォームでのみ使用可能であると記載されていますが、32ビットプラットフォームでもint64_tを解析する必要があります。

私のパーサーからの抜粋は次のとおりです。

...
  eps(_b == VALUE_INT4) >> qi::long_ 
    [phoenix::bind(&AddEntry, _r1,_a, _1, _pass)] ) // 
| ( eps(_b == VALUE_INT8) >> qi::long_long)
...

AddEntryにはint32_tオーバーロードとint64_tオーバーロードがありますが、phoenix :: static_cast_は順番にオン_1になっていますか?この場合、最新の32ビットプラットフォームで64ビット整数を解析するにはどうすればよいですか?8008BOOST_HAS_LONG_LONGのような古風なハードウェアでは定義されていないだけだと思います;)。

<Rant> 彼らがc99で設定された標準に固執していればよかった<boost/cstdint.hpp>のですが、私たちのほとんどはクリーンな抽象化に対してプログラミングしたいと思っています。数値パーサーがそのように定義されているのには、おそらく正当な理由があります。ただし、グランドスキームの使用は、ドキュメントでより適切に定義できます。 </Rant>

補足:上記の条件付きイプシロンスタイルは、パフォーマンスのケースステートメントに匹敵しますか?

4

2 に答える 2

1

1)Qiパーサーはすでにオーバーフロー条件をチェックしています。コンポーネントが一致するはずのタイプで入力を表現できない場合、パーサーコンポーネントは失敗します。たとえばint_parser<int32_t, 10>、符号付き32ビット整数に適合しない数値の場合は失敗します。

long_longが定義されている場合にのみ、パーサー(つまり、事前定義された64ビット整数パーサー)を使用できますBOOST_HAS_LONG_LONG。これが当てはまらないプラットフォームを使用している場合でも、Qi数値パーサー(ここを参照)で期待される機能を公開する独自のラッパータイプを作成することで、64ビット整数をエミュレートできます。

struct my_64bit_int {
    //...
};
typedef int_parser<my_64bit_int, 10> my_64bit_int_parser_type;
my_64bit_int_parser_type const my_64bit_int_parser;

そしてそれを次のように使用します:

my_64bit_int bigint;
parse(b, e, my_64bit_int_parser, bigint);

2)コンパイラを支援せずにオーバーロードされた関数をバインドすることはできません。つまり、次のようになります。

void AddEntry(int32_t);
void AddEntry(int64_t);

int32_t:にバインドする場合は、関数ポインタを明示的にキャストする必要があります。

phoenix::bind((void(*)(int32_t))&AddEntry, _1);

補足への回答:いいえ。代替パーサーは常に、指定されたのと同じ順序で異なる代替を順次実行し、それらの最初のものが一致すると停止します。その全体的な複雑さはですO(N)。ここNで、は個別の選択肢の数です(ここを参照)。

于 2011-04-06T19:22:48.570 に答える
0

これらのtemplatasは、必要なセマンティクスを取得します。

qi::int_parser< int32_t,  10, 1,10>  p_int32_t;
qi::int_parser< int64_t, 10, 1, 19> p_int64_t;

これらのパーサーはユニットテストされ、オーバーフロー時に期待エラーが発生しました。つまり、それぞれの場合>= 2^31>= 2^63です。

過負荷はphoenix::bind afaikによって検出されません(間違っている場合は修正してください)、

したがって、の線に沿ったマクロ

#define  ADD_ENTRY(TP,prefix)                                           \
    void AddEntry_##prefix( value_variant_vector & v, uint32_t ordinal, \
                            TP entry, bool & ok_)                       \

興味のある方のために、コンパイラのエラーメッセージは次のとおりです(AddEntryがテンプレート関数の場合)。

/opt/dev_64_swat/dsl/src/parser/RowAndTable.cc:43: error: no matching function 
for call to ‘bind(<unresolved overloaded function type>, const
boost::phoenix::actor<boost::spirit::attribute<1> >&, const 
boost::phoenix::actor<boost::spirit::local_variable<0> >&, const 
boost::phoenix::actor<boost::spirit::argument<0> >&, const   
boost::phoenix::actor<boost::phoenix::argument<2> >&)’

手書きのオーバーロードでもエラーが発生します。

于 2011-04-06T13:40:44.210 に答える