読者です 読者をやめる 読者になる 読者になる

C++1z ロケール依存なし、フォーマット解析なしの高速な文字列・数値変換

C++

C++1zから、低レイヤーの文字列・数値間の変換関数が導入されます。これは、ハイパフォーマンスな文字列処理をするための基礎を提供することを目的としています。

数値から文字列への変換はto_chars()、文字列から数値への変換はfrom_chars()という関数です。これらの関数は、以下の特徴があります。

  • ロケールはCロケール (POSIXロケール) 固定
  • 関数内での動的メモリ確保なし
  • フォーマットはパラメータとして与え、自動的にフォーマットを解析することはない
  • 使用できるフォーマットも最小限
    • +符号の指定はできない
    • 文字列中のスペースは許容されない
    • #による小数点以下の桁数指定はできない
    • ゼロ埋めはできない
    • 小文字のみ許容し、大文字は扱えない
    • 16進数に0xは付けられない
  • 例外送出なし
#include <iostream>
#include <utility>
#include <limits>

int main()
{
    {
        char str[std::numeric_limits<int>::digits10 + 2] = {0}; // '-' + NULL
        int input = 123456;

        // 整数inputを10進数で文字列に変換し、strに出力
        std::to_chars(std::begin(str), std::end(str), input, 10);
        std::cout << str << std::endl; // 123456
    }
    {
        const char input[] = "-123456";
        int value = 0;

        // 10進数の整数が入った文字列を、intに変換
        std::from_chars(std::begin(input), std::end(input), value);
        std::cout << value << std::endl; // -123456
    }
}

宣言

// <utility>
namespace std {
    // 数値から文字列への変換
    struct to_chars_result {
        char* ptr;
        bool overflow;
    };

    to_chars_result to_chars(char* first, char* last, see below value, int base = 10); // 整数版
    to_chars_result to_chars(char* first, char* last, float       value, bool hex = false);
    to_chars_result to_chars(char* first, char* last, double      value, bool hex = false);
    to_chars_result to_chars(char* first, char* last, long double value, bool hex = false);


    // 文字列から数値への変換
    enum class chars_format {
        scientific = unspecified,
        fixed = unspecified,
        hex = unspecified,
        general = fixed | scientific
    };

    to_chars_result to_chars(char* first, char* last, float       value, chars_format fmt, int precision = 6);
    to_chars_result to_chars(char* first, char* last, double      value, chars_format fmt, int precision = 6);
    to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt, int precision = 6);


    struct from_chars_result {
        const char* ptr;
        error_code ec;
    };

    from_chars_result from_chars(const char* first, const char* last, see below& value, int base = 10); // 整数版

    from_chars_result from_chars(const char* first, const char* last, float& value, chars_format fmt = chars_format::general);
    from_chars_result from_chars(const char* first, const char* last, double& value, chars_format fmt = chars_format::general);
    from_chars_result from_chars(const char* first, const char* last, long double& value,  chars_format fmt = chars_format::general);
}

参照

お断り

この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。