5

コマンドライン引数を取得して使用している状況がありますboost::lexical_cast<unsigned long>(my_param)。my_param の負の値によって lexical_cast がスローされることを期待していましたが、代わりに、-1 が になるように喜んで変換されます18446744073709551615。unsigned long の最大値は 2^32-1 であり、unsigned long long のように見えます。

したがって、char * 入力を unsigned long にキャストするよりスマートな方法、または大きな unsigned long long に変装して負の値を受け入れていないことを確認する方法を探しています。

4

2 に答える 2

6

なぜそのように動作するのかを説明する、問題のあるブーストに対するバグレポートがあります。

boost::lexical_cast には stringstream の動作があり、std::locale の num_get 関数を使用して数値を変換します。[22.2.2.1.2] プログラミング言語 — C++ (または [22.2.2.1.2] Working Draft, Standard for Programming Language C++) を見ると、num_get が変換に scanf の規則を使用していることがわかります。 . %u の C99 標準では、入力値のマイナス記号はオプションであるため、負の数を読み取ってもエラーは発生せず、結果は 2 の補数になります。

また、推奨されるラッパーの回避策:

https://svn.boost.org/trac/boost/ticket/5494

于 2012-11-02T16:15:50.177 に答える
0

それはまさに、標準に従って負の値がどのように扱われるかです。それらはモジュロ 2 N演算を使用します。これにより、便利なトリックが可能になります。-1 を、あるタイプの可能な最大の符号なし値の省略形として使用します。

この変換が気に入らない場合は、変換を行う前に入力をスキャンしてマイナス記号を探す必要があります。

于 2012-11-02T16:13:52.040 に答える