なぜstd :: stouがないのですか?


96

C ++ 11はいくつかの新しい文字列変換関数を追加しました:

http://en.cppreference.com/w/cpp/string/basic_string/stoul

これには、stoi(文字列からint)、stol(文字列からlong)、stoll(文字列からlong long)、stoul(文字列からunsigned long)、stoull(文字列からunsigned long long)が含まれます。その不在で注目すべきは、stou(文字列から符号なし)関数です。それが必要ではないが、他のすべてが必要な理由はありますか?

関連:C ++ 11には「sto {short、unsigned short}」関数はありませんか?


6
私の質問は、「stoulを使用するだけの明らかでない欠点はありますか」という説明に沿ったものでした。明らかにそれはテンプレートのインスタンス化を台無しにするでしょうが、私が考慮していない他のものはありますか?それが除外された理由についてのコメントはいいですが、二次的でしょう。
David Stone、

12
@NicolBolasこれが建設的でない理由がわかりません。私はこの矛盾の理由を見つけることができず、回答者はいくつかの存在する可能性のある有効であるがその明白な理由ではないことに洞察を与えるかもしれないので、それは完全に有効な質問です。
Christian Rau

4
ので@SethCarnegieまあ、何をお使いのプラットフォーム(そしておそらくプラットフォームの大多数)行うことは、単に無関係ではないunsigned longだけで何ですunsigned int
Christian Rau

4
@SethCarnegie:私の一般的なコンピューターでunsigned longは、64ビット、unsigned int32です。これらは異なるタイプであり、互いに同じであると想定することはできません。
Mike Seymour

2
@NicolBolas言ったように、OP(および私)は、それが投機的であることを知りません。C++の言語の内部に深く埋め込まれた正当な正当な理由があり得るためです。しかし、あなたがそれが投機的であると言うので、私はそのような理由はないと思います。しかし、繰り返しになりますが、おそらくC ++ 11を担当する人が答えることができます。これは「ワウワウ、どこにあるのかstou」という質問ではありませんが、この明らかな矛盾の明確な理由を尋ねる質問です。そのような理由がないことがわかっている場合は、それを回答として投稿してください。
Christian Rau

回答:


29

ほとんどのパットの答えはCライブラリは、「何の対応を持っていないことになりますstrtou:」、およびC ++ 11文字列関数は、すべてのCライブラリ関数の周りだけで薄くベールに包まれたラッパーでstd::sto*機能ミラーstrto*、およびstd::to_string機能が使用しますsprintf


編集:KennyTMが指摘するように、stoiとは両方とも基礎となる変換関数としてstol使用さstrtolれますが、stoulを使用するが存在するstrtoulのに対応するが存在しないのはなぜか不思議stouです。


14
C ++委員会がそのようなCっぽいアプローチを採用することにした理由を知っていますか?のようなboost::lexical_cast<>()ものは、よりC ++のやり方のようです。
ポールマンタ2012年

2
これらの実装の詳細は本当に標準で定義されていますか?
オービットのライトネスレース

4
@LightnessRacesinOrbit:の場合sto*、C ++ 11 21.5 / 1:効果:最初の2つの関数はstrtol(str.c_str()、ptr、base)を呼び出し、最後の3つの関数はstrtoul(str.c_str()、ptr、baseを呼び出します) )、strtoll(str.c_str()、ptr、base)、およびstrtoull(str.c_str()、ptr、base)をそれぞれ使用します。
マイクシーモア

12
C ++標準には「...を呼び出して実装する必要がある」と記載されているかどうかは関係ありません。C++標準にはまだグローバルなas-ifルールがあるstd::sto*ためです。有効なプログラムは、それらが密かに別の方法で実装されているわけではなく、実装が有効であることを認識できません。

2
完全にトピック外ですが、Boost / lexical_castのようにiostreamを使用しないことの実際的な理由は、純粋なパフォーマンスです。iostreamはstrtoulなどに対してかなりのマージンを失うと思います。
Kerrek SB、2012

22

なぜstoi存在するのかはわかりませんstouが、stoulと仮定の唯一の違いはstou、結果が次の範囲内にあるかどうかのチェックですunsigned

unsigned stou(std::string const & str, size_t * idx = 0, int base = 10) {
    unsigned long result = std::stoul(str, idx, base);
    if (result > std::numeric_limits<unsigned>::max()) {
        throw std::out_of_range("stou");
    }
    return result;
}

(同様に、範囲チェックも異なりますが、にstoiも似stolていますが、既に存在しているため、実装方法を正確に心配する必要はありません。)


stoiand stol、またはstoland の違いはstoll、範囲チェックのみです。
Hossein 2012年

1
@Hossein:間stoistol、はい。ただし、範囲チェックのみが異なるわけstolstollはなく、異なるライブラリ関数を呼び出します。
Ben Voigt 2014

0
unsigned long ulval = std::stoul(buf);
unsigned long mask = ~0xffffffffl;
unsigned int uival;
if( (ulval & mask) == 0 )
    uival = (unsigned int)ulval;
else {
    ...range error...
}

マスクを使用して、マスクで表現されたビット単位の期待値サイズでこれを行うと、64ビットのlong型と32ビットのint型の両方で機能しますが、32ビットのlong型と32ビットの整数型でも機能します。

64ビットlongの場合、〜0xfffffffflは0xffffffff00000000になるため、上位32ビットのいずれかが設定されているかどうかがわかります。32ビットlongでは、〜0xfffffffflは0x00000000になり、マスクチェックは常にゼロになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.