最終更新日時: 2025年12月03日 22時42分25秒 (JST)
K10-K10 が更新

履歴 編集

function
<string>

# std::stold(C++11)

    namespace std {
      long double stold(const std::string& str, std::size_t* idx = nullptr);  // (1)
      long double stold(const std::wstring& str, std::size_t* idx = nullptr); // (2)
    }

## 概要

文字列`str`を数値として読み取って、`long double`型の値に変換する。

## 効果

パラメータ`str`が`string`型であれば`std::strtold(str.c_str(), &end)`、`wstring`型であれば`std::wcstold(str.c_str(), &end)`を呼び出して、その戻り値を返す。

`idx`が非`nullptr`の場合、変換に使用されなかった要素のインデックス（`end - str.c_str()`）が格納される。

## 戻り値

変換して得られた数値が返される。

## 例外

- 数値への変換が行われなかった場合、`std::invalid_argument`が送出される。
- 以下の条件に合致した場合、`std::out_of_range`が送出される。
  - `std::strtold()`関数が`errno`変数に`ERANGE`を設定した場合
  - 結果が範囲外の値になった場合 (C++14)

## 備考

### errnoの扱い

- Visual C++ 11やGCC (libstdc++) 4.8.2では、この関数を呼び出すと`errno`の値が変更される。
- Clang (libc++) 3.3では、この関数の呼び出し前後で`errno`の値は変化しない。

### グローバルロケールの影響

この関数は、`setlocale()`関数により挙動が変化する。

- `strtold()`関数での文字列先頭の空白を読み飛ばす処理に、`<cctype>`の`isspace()`関数が使用される。
- 小数点記号は`LC_NUMERIC`で指定されたものが使用される。

## 例

    #include <iostream>
    #include <string>

    int main()
    {
      // 10進法での変換
      std::cout << "---- decimal point" << std::endl;

      long double a = std::stold("1.5"); // std::stold("1.5", nullptr);
      std::cout << a << std::endl;

      long double aw = std::stold(L"1."); // std::stold(L"1.", nullptr);
      std::cout << aw << std::endl;

      // 指数表記の変換
      std::cout << "---- base = 8" << std::endl;

      long double b = std::stold("0.5e3", nullptr);
      std::cout << b << std::endl;

      long double bw = std::stold(L".25e3", nullptr);
      std::cout << bw << std::endl;

      // 16進法での変換
      std::cout << "---- base = 16" << std::endl;

      long double c = std::stold("0x1.2P3", nullptr);
      std::cout << c << std::endl;

      long double cw = std::stold(L"0x1.2P4", nullptr);
      std::cout << cw << std::endl;

      // 2番目の仮引数の使用例
      std::cout << "---- use of idx parameter" << std::endl;

      std::string es = "30.75%";
      std::size_t ei;
      long double e = std::stold(es, &ei);
      std::cout << e << ' ' << es[ei] << std::endl;

      std::wstring ews = L"32%";
      std::size_t ewi;
      long double ew = std::stold(ews, &ewi);
      std::cout << ew << ' ' << ewi << std::endl;

      // 文字列先頭に空白がある場合
      std::cout << "---- space character before number" << std::endl;
      std::cout << std::stold("    -1") << std::endl;
      std::cout << std::stold(L"    -.25") << std::endl;
    }

### 出力例

    ---- decimal point
    1.5
    1
    ---- base = 8
    500
    250
    ---- base = 16
    9
    18
    ---- use of idx parameter
    30.75 %
    32 2
    ---- space character before number
    -1
    -0.25

## 実装例

    long double stold(const std::string& str, std::size_t* idx = nullptr) {
      const char* p = str.c_str();
      char* end;
      errno = 0;
      long double x = std::strtold(p, &end);
      if (p == end) {
        throw std::invalid_argument("stold");
      }
      if (errno == ERANGE) {
        throw std::out_of_range("stold");
      }
      if (idx != nullptr) {
        *idx = static_cast<std::size_t>(end - p);
      }
      return x;
    }

    long double stold(const std::wstring& str, std::size_t* idx = nullptr) {
      const wchar_t* p = str.c_str();
      wchar_t* end;
      errno = 0;
      long double x = std::wcstold(p, &end);
      if (p == end) {
        throw std::invalid_argument("stold");
      }
      if (errno == ERANGE) {
        throw std::out_of_range("stold");
      }
      if (idx != nullptr) {
        *idx = static_cast<std::size_t>(end - p);
      }
      return x;
    }

## バージョン

### 言語

- C++11

### 処理系

- Clang: ?
- GCC: ?
- ICC: ?
- Visual C++: 2010 ✅, 2012 ✅, 2013 ✅

ただし、Visual C++ 10.0, 11.0は十六進法に対応していない（12.0は未確認）。

## 関連リンク

### C標準ライブラリに由来する関数

- `atof`: `stold`は`atof`を`std::string`および`std::wstring`に対応させ、戻り値の型を`long double`に変更したものと見なせる。
- `strtold`, `wcstold`: `stold`は`strtold`および`wcstold`をそれぞれ`std::string`と`std::wstring`に対応させたものと見なせる。

### ファミリー

- `stoi`: 戻り値の型が`int`となったもの。
- `stol`: 戻り値の型が`long`となったもの。
- `stoll`: 戻り値の型が`long long`となったもの。
- `stoul`: 戻り値の型が`unsigned long`となったもの。
- `stoull`: 戻り値の型が`unsigned long long`となったもの。
- `stof`: 戻り値の型が`float`となったもの。
- `stod`: 戻り値の型が`double`となったもの。
- (`stold`: この関数自身)

### ロケール依存しない高速な変換関数

- `from_chars`

## 参照

- N2408 Simple Numeric Access Revision 2
- LWG Issue 2009. Reporting out-of-bound values on numeric string conversions