16490
`C++11`で`std::stoi`が追加されていますが、`std::stoui`がありません。これはなぜですか？  
`std::stoul`や`std::stoull`はあるのに…

また`unsigned int`に入れるためにはどうするのがベストでしょうか。
CC BY-SA 3.0
2015-09-10T09:15:43.280
16470
2015-09-11T02:33:11.133
7214
question
c++ c++11
C++11にstd::stouiがないのはなぜ？
長文につき回答欄を使いますが回答にあらず

「なぜ」に答えられるのは [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") 規格委員会
JTC1/SC22 の委員ぐらいのもので、  
オイラたち一般ユーザとしては推して知るべしに留まるわけです。  
Rationale (根拠) が公開議事録に残っていればいいのですが探すのは困難です。

ここは日本語 SO なので本家の記事をちょっと意訳すると  
<https://stackoverflow.com/questions/8715213/>  
<https://stackoverflow.com/questions/7895583/>

[c](/questions/tagged/c "'c' のタグが付いた質問を表示") 規格書 ISO/IEC 9899:1999 の 7.20
が定めている [strto系] [ato系] 標準関数は  
`atof` (名前に反して `double` に変換する)  
`atoi` `atol` `atoll`  
`strtod` `strtof` `strtold` `strtol` `strtoll` `strtoul` `strtoull`  
だけであり [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示")
もそれに倣ったのではないか、と推測されています。

オイラの注釈：要するに [c](/questions/tagged/c "'c' のタグが付いた質問を表示") に strtoui (unsigned
int) や strtos (short) は欠けている  
同様に [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") も stoui や stos
が欠けている

この辺から、なんとなく  
\- [c](/questions/tagged/c "'c' のタグが付いた質問を表示") で要らないと判断された型への変換は
[c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") でも要らないと判断したとか  
(疑問が「なぜ [c](/questions/tagged/c "'c' のタグが付いた質問を表示") で要らないと判断したか」に移るだけですが)  
\- [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") で書かれたソースコードを
[c](/questions/tagged/c "'c' のタグが付いた質問を表示") に移植する際に [c](/questions/tagged/c
"'c' のタグが付いた質問を表示") 側に適切な変換関数が無いものは移植困難になるから、わざと搭載しなかったとか  
\- [c](/questions/tagged/c "'c' のタグが付いた質問を表示") の標準関数の変換関数の挙動と厳密に同じ変換関数が欲しかったから
[c](/questions/tagged/c "'c' のタグが付いた質問を表示") に無い変換は無いべきと判断したとか

まあ何の役にも立たないただの妄想ですけど

で、ではどうやって `unsigned int` `short` に値を格納すると良いか、ですが  
\- 昔からある `std::istringstream` でもよさそうですし  
\- [boost](/questions/tagged/boost "'boost' のタグが付いた質問を表示") を使ってよいなら
`boost::lexical_cast` でもよさそうですし  
\- `std` の中の実装まで追っかけて自前で類似の `stoui` `stos` を実装してもよさそうですし  
（処理系を超える互換性はなくなりますが）  
\- 既にある `stoul` を使い `unsigned long` の値を得た後 `numeric_limits<unsigned int>`
で上下限を切る wrapper を実装してもよさそうですし

っていうか [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") 的には
`template<typename T> T fromstring(...)` なんてほうが自然っぽいし、  
そういう選択をしなかった根拠は提示されてもよさそうな気がします。
CC BY-SA 3.0
2015-09-11T00:46:19.883
16490
2015-09-11T01:28:22.600
2017-05-23T12:38:56.083
-1
8589
16470
answer
一応`std::istringstream`での実装を回答しておきます。  
エラーチェックが必要ならば`std::istringstream::fail()`や`std::istringstream::eof()`を使います。

参考URL：  
<http://d.hatena.ne.jp/xanthus/20071011/p1>

```

    unsigned int StringToUInt(const std::string& input)
    {
        std::istringstream iss(input);
        unsigned int output = 0;
        iss >> output;
        return output;
    }
    
```

テンプレート版も一応…  
ただ、`std::stoi`等を無視することになるため、悩ましいところです。

```

    template<typename T> T StringToNumericalValue(const std::string& input)
    {
        std::istringstream iss(input);
        T output = 0;
        iss >> output;
        return output;
    }
    
```
CC BY-SA 3.0
2015-09-11T02:31:42.563
16501
2015-09-11T02:31:42.563
7214
16470
answer
C++11で追加された`stoXX`変換関数群では、初期提案 [N1803 Simple Numeric Access](http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2005/n1803.html)
時点から`stoui`は存在しなかったようです。残念ながら一連の提案文書にRationale記載もなく、「なぜ？」に答えることができません。

本当に`stoui`が必要なら、下記コードでエミュレーションできます。（[libstdc++](https://github.com/gcc-
mirror/gcc/blob/gcc-5-branch/libstdc++-v3/include/ext/string_conversions.h#L50-L78)実装を参考にしました）

```

    #include <string>
    #include <limits>
    #include <exception>
    #include <cstdlib>
    #include <cerrno>
    
    unsigned int stoui(const std::string& str, std::size_t* pos = 0, int base = 10)
    {
      const char *s = str.c_str();
      char *endptr;
      errno = 0;
      unsigned long val = std::strtoul(s, &endptr, base);
      if (endptr == s)
        throw std::invalid_argument("stoui");
      if (errno == ERANGE || std::numeric_limits<unsigned int>::max() < val)
        throw std::out_of_range("stoui");
      if (pos)
        *pos = endptr - s;
      return static_cast<unsigned int>(val);
    }
    
```
CC BY-SA 3.0
2015-09-11T02:33:11.133
16502
2015-09-11T02:33:11.133
49
16470
answer