プログラミング/C++/C++11 既存ライブラリ変更点/ユーティリティ のバックアップ(No.1)


C++03規格時点で存在したユーティリティライブラリに対するC++11規格での変更点をまとめています。

概要

当文書では、特定のカテゴリに含まれないヘッダファイル群について、C++11規格での変更点をまとめている。

共通の変更点

ここに記載した内容は個々のヘッダファイルの項には記載しない。

  • 各クラスの throw() 指定されていたコンストラクタおよびメンバ関数から指定が外され、代わりに 条件式なしの noexcept 指定が付与された。

  • 各クラスの throw() 指定されていたデストラクタから指定が外された。
    代わりには何も指定されないが、C++11規格により暗黙の noexcept となる。

  • throw() 指定されていたフリー関数から指定が外され、代わりに 条件式なしの noexcept 指定が付与された。

<exception>

  • 下記のクラスが定義された。

    // 例外を保持するスマートポインタ。
    class exception_ptr;
    // ネストした例外を表す。基本的に直接用いることはない。
    class nested_exception;
  • 下記のフリー関数が定義された。

    // set_terminate で設定した terminate_handler 関数を取得する。
    terminate_handler get_terminate() noexcept;
    // set_unexpected で設定した unexpected_handler 関数を取得する。
    unexpected_handler get_unexpected() noexcept;
    // 現在ハンドル中の例外を取得する。
    exception_ptr current_exception() noexcept;
    // exception_ptr が保持する例外を送出する。
    [[noreturn]] void rethrow_exception(exception_ptr ep);
    // 例外を保持する exception_ptr を作成する。
    template<class E> exception_ptr make_exception_ptr(E e) noexcept;
    // 現在の例外をネストさせた例外 e を送出する。
    [[noreturn]] template<class T> void throw_with_nested(T&& e);
    // e が例外をネストしているならばその例外を送出する。そうでなければ何もしない。
    template<class T> void rethrow_if_nested(const T& e);
  • 下記のフリー関数に [[noreturn]] 属性が指定された。

    • terminate
    • unexpected

<locale>

locale クラス

  • 下記のコンストラクタが追加された。

    explicit locale(const string& loc_name);
    locale (const locale& src, const string& loc_name, category categories);

local::facet クラス

  • コピーコンストラクタおよびコピー代入演算子が private 宣言から publicdelete 指定になった。

local::id クラス

  • コピーコンストラクタおよびコピー代入演算子が private 宣言から publicdelete 指定になった。

ctype_base クラス

  • メンバ型 maskenum 型でなくともビットマスク定数を定義可能な型であれば構わなくなった。
    整数型や bitset クラステンプレートが利用される可能性がある。

  • メンバ定数 blank が追加された。
    空白文字カテゴリを表すビットマスク値(ctype_base::mask 型)である。

ctype クラステンプレート

local::facet クラスおよび ctype_base クラスを継承しており、継承元の変更点も引き継ぐ。

  • ctype<char> 特殊化バージョンで定義されるメンバ関数 table および静的メンバ関数 classic_table のアクセスレベルが protected から public に変更された。

codecvt クラステンプレート

local::facet クラスを継承しており、それらの変更点も引き継ぐ。

  • 下記の特殊化バージョンが定義され、すべての標準 locale オブジェクトがこれらをサポートするようになった。

    template<> class codecvt<char16_t, char, mbstate_t>;
    template<> class codecvt<char32_t, char, mbstate_t>;

num_get クラステンプレート

local::facet クラスを継承しており、それらの変更点も引き継ぐ。

  • 下記のメンバ関数オーバロードが定義された。

    iter_type get(
        iter_type first,
        iter_type last,
        ios_base& in,
        ios_base::iostate& err,
        long long& value) const;
    iter_type get(
        iter_type first,
        iter_type last,
        ios_base& in,
        ios_base::iostate& err,
        unsigned long long& value) const;
    protected:
    virtual iter_type do_get(
        iter_type first,
        iter_type last,
        ios_base& in,
        ios_base::iostate& err,
        long long& value) const;
    protected:
    virtual iter_type do_get(
        iter_type first,
        iter_type last,
        ios_base& in,
        ios_base::iostate& err,
        unsigned long long& value) const;

num_put クラステンプレート

local::facet クラスを継承しており、それらの変更点も引き継ぐ。

  • 下記のメンバ関数オーバロードが定義された。

    iter_type put(iter_type first, ios_base& out, char_type c, long long value) const;
    iter_type put(
        iter_type first,
        ios_base& out,
        char_type c,
        unsigned long long value) const;
    protected:
    virtual iter_type do_put(
        iter_type first,
        ios_base& out,
        char_type c,
        long long value) const;
    protected:
    virtual iter_type do_put(
        iter_type first,
        ios_base& out,
        char_type c,
        unsigned long long value) const;

time_get クラステンプレート

local::facet クラスを継承しており、それらの変更点も引き継ぐ。

  • 下記のメンバ関数が定義された。

    // 日時文字列を解析する。
    iter_type get(
        iter_type first,
        iter_type last,
        ios_base& in,
        ios_base::iostate& err,
        tm* t,
        char format,
        char modifier = 0) const;
    iter_type get(
        iter_type first,
        iter_type last,
        ios_base& in,
        ios_base::iostate& err,
        tm* t,
        const char_type* format_begin,
        const char_type* format_end) const;
    // 日時文字列を解析する。
    protected:
    virtual iter_type do_get(
        iter_type first,
        iter_type last,
        ios_base& in,
        ios_base::iostate& err,
        tm* t,
        char format,
        char modifier = 0) const;

<locale> その他

  • 下記のクラステンプレートが定義された。

    // ワイド文字列とバイト文字列間のコード変換処理を提供するクラス。
    template<
        class Codecvt,
        class WcharT = wchar_t,
        class WcharAlloc = allocator<WcharT>,
        class ByteAlloc = allocator<char>>
    class wstring_convert;
    // コード変換処理を行うストリームバッファクラス。
    template<
        class Codecvt,
        class WcharT = wchar_t,
        class Traits = char_traits<WcharT>>
    class wbuffer_convert : public basic_streambuf<WcharT, Traits>;
  • 名前の末尾が _byname であるクラステンプレート C_bynamectype_bynamecodecvt_byname 等)に下記のコンストラクタが定義された。
    またそれらのクラスは C を継承しており、継承元の変更点も引き継ぐ。

    explicit C_byname(const string& loc_name, size_t refs = 0);
  • 下記のフリー関数が定義された。

    // ロケール loc に従い、 c が空白文字か否かを調べる。
    template<class CharT>
    bool isblank(CharT c, const locale& loc);

<memory>

allocator クラステンプレート

  • メンバ型 propagate_on_container_move_assignment が定義された。

    // true_type ならば、このアロケータを保持するコンテナがムーブされるときに
    // アロケータをムーブ先にコピーする。
    typedef true_type propagate_on_container_move_assignment;
  • メンバ関数 construct の定義が変更された。

    // C++03
    // ::new((void*)p) value_type(value) を返す。
    void construct(pointer p, const_reference value);
    // C++11
    // ::new((void*)p) U(forward<Args>(args)...) を返す。
    template<class U, class ...Args>
    void construct(U* p, Args&&... args);
  • メンバ関数 destroy の定義が変更された。

    // C++03
    // p->~value_type() を呼び出す。
    void destroy(pointer p);
    // C++11
    // p->~U() を呼び出す。
    template<class U>
    void destroy(U* p);
  • メンバ関数 address に条件式なしの noexcept 指定が付与され、例外を投げないことが保証された。

<memory> その他

  • 下記のクラステンプレートが定義された。

    // 既定のオブジェクトデリータ。
    // 渡されたポインタに対して delete または delete[] を呼び出す。
    template<class T> class default_delete;
    template<class T> class default_delete<T[]>; // delete[] 版
    
    // オブジェクトの所有権を共有するスマートポインタ。
    template<class T> class shared_ptr;
    // オブジェクトの唯一の所有権を保持するスマートポインタ。
    template<class T, class Deleter = default_delete<T>> class unique_ptr;
    template<class T, class Deleter> class unique_ptr<T[], Deleter>;
    // shared_ptr への弱参照を保持するスマートポインタ。
    template<class T> class weak_ptr;
    // クラス C が enable_shared_from_this<C> を public 継承することで、
    // 自分自身への shared_ptr<C> を取り出すメンバ関数 shared_from_this を定義する。
    template<class T> class enable_shared_from_this;
    // shared_ptr<T> または weak_ptr<T> の2引数 a, b をとり、
    // a.owner_before(b) を返す関数オブジェクトクラス。
    template<class Ptr> struct owner_less; // 未定義
    template<class T> struct owner_less<shared_ptr<T>>;
    template<class T> struct owner_less<weak_ptr<T>>;
    // スマートポインタ型や生ポインタ型の型情報を提供する。
    template<class Ptr> class pointer_traits;
    template<class T> class pointer_traits<T*>;
    // アロケータ型の型情報を提供する。
    template<class Alloc> struct allocator_traits;
    // 型 T がアロケータ Alloc を持つか否かを静的メンバ定数 value で提供する。
    // 特定の型 T について特殊化や部分特殊化されていない場合、 value の値は
    // is_convertible<Alloc, typename T::allocator_type>::value と等価である。
    template<class T, class Alloc> struct uses_allocator;
  • 下記のフリー関数が定義された。

    // new T{ std::forward<Args>(args)... } 相当の値を保持する shared_ptr を作成する。
    template<class T, class ...Args>
    shared_ptr<T> make_shared(Args&&... args);
    // make_shared のアロケータ指定版。
    template<class T, class Alloc, class ...Args>
    shared_ptr<T> allocate_shared(const Alloc& alloc, Args&&... args);
    // static_cast<T*>(p.get()) 相当のキャストを行った shared_ptr を作成する。
    template<class T, class U>
    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& p) noexcept;
    // dynamic_cast<T*>(p.get()) 相当のキャストを行った shared_ptr を作成する。
    template<class T, class U>
    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& p) noexcept;
    // const_cast<T*>(p.get()) 相当のキャストを行った shared_ptr を作成する。
    template<class T, class U>
    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& p) noexcept;
    // p がデリータを保持していれば取得する。保持していなければ nullptr を返す。
    template<class Deleter, class T>
    Deleter* get_deleter(const shared_ptr<T>& p) noexcept;
    // 型 T の operator& がオーバロードされているか否かに関わらず
    // value の実アドレス値を取得する。
    template<class T> T* addressof(T& value) noexcept;
    // 空きサイズ space バイトのバッファの先頭を指すポインタ p から
    // alignment バイトでアラインメントされた size バイト分の領域を検索し、
    // 見つかった場合は p と space の値を更新して p を返す。
    // 見つからなかった場合は nullptr を返す。
    void* align(size_t alignment, size_t size, void*& p, size_t& space);
    // uninitialized_copy のコピー個数指定版。コピーの終端位置を指すイテレータを返す。
    template<class InputIterator, class Size, class ForwardIterator>
    ForwardIterator uninitialized_copy_n(
        InputIterator first,
        Size size,
        ForwardIterator result);
    // get_pointer_safety の戻り値となる列挙クラス。
    enum class pointer_safety
    {
        relaxed,    // safety-derived なポインタとそうでないポインタを区別しない。
        preferred,  // relaxed と同様だが、リークに関するレポートの実装を許可する。
        strict,     // safety-derived なポインタとそうでないポインタを区別する。
    };
    
    // ポインタ安全性に関する挙動種別を取得する。
    // 既存の多くの処理系では pointer_safety::relaxed が返る。
    pointer_safety get_pointer_safety() noexcept;
    // ガベージコレクションに関する関数群。
    void declare_reachable(void* p);
    template<class T> T* undeclare_reachable(T* p);
    void declare_no_pointers(char* p, size_t size);
    void undeclare_no_pointers(char* p, size_t size);
  • 定数 allocator_arg とその型 allocator_arg_t が定義された。
    @code{tuple} や function 等のコンストラクタでアロケータを指定する場合に、他のコンストラクタオーバロードとの曖昧さを回避するために第1引数に指定する。

  • フリー関数 get_temporary_buffer に条件式なしの noexcept 指定が付与され、例外を投げないことが保証された。

  • フリー関数 uninitialized_fill_n の定義が変更され、コピーの終端位置を指すイテレータを返すようになった。

  • クラステンプレート auto_ptr が非推奨となった。

<new>

  • 下記の関数が追加された。

    // set_new_handler で設定した new_handler 関数を取得する。
    new_handler get_new_handler() noexcept;
  • 下記の関数オーバロードから throw(bad_alloc) 指定が外された。

    // C++03
    void* operator new(std::size_t size) throw(std::bad_alloc);
    void* operator new[](std::size_t size) throw(std::bad_alloc);

<stdexcept>

  • 下記のクラスに const char* を第1引数にとるコンストラクタオーバロードが定義された。

    • logic_error
    • domain_error
    • invalid_argument
    • length_error
    • out_of_range
    • runtime_error
    • range_error
    • overflow_error
    • underflow_error

<typeinfo>

type_info クラス

  • 下記のメンバ関数が追加された。

    // 型のIDを表すハッシュコード値を取得する。
    size_t hash_code() const noexcept;
  • 下記のメンバ関数に条件式なしの noexcept 指定が付与され、例外を投げないことが保証された。

    • before
    • name
    • operator==
    • operator!=

<utility>

pair クラステンプレート

  • 下記のメンバ関数が定義された。

    // 2つの pair 間で内容を入れ替える。
    void swap(pair& other)
        noexcept(
            noexcept(swap(first, other.first)) &&
            noexcept(swap(second, other.second)));
  • 下記のコンストラクタオーバロードが定義された。

    template<class U1, class U2> pair(pair<U1, U2>&& src);
    pair(const pair& src) = default;
    pair(pair&& src) = default;
    template<class U1, class U2> pair(U1&& first, U2&& second);
    
    // first_args を first_type のコンストラクタ引数列、
    // second_args を second_type のコンストラクタ引数列としてインスタンスを生成する。
    // first_type や second_type がコピーもムーブも不可な型である場合に有用。
    template<class ...Args1, class ...Args2> pair(
        piecewise_construct_t pc,
        tuple<Args1...> first_args,
        tuple<Args2...> second_args);
  • 引数なしのコンストラクタの定義に constexpr が付き、コンパイル時定数として利用可能になった。

  • 下記のメンバ関数オーバロードが定義された。

    template<class U1, class U2> pair& operator=(const pair<U1, U2>& src);
    pair& operator=(pair&& src)
        noexcept(
            is_nothrow_move_assignable<first_type>::value &&
            is_nothrow_move_assignable<second_type>::value);
    template<class U1, class U2> pair& operator=(pair<U1, U2>&& src);

<utility> その他

  • 下記のクラステンプレートが定義された。

    // テンプレート引数 I が 0 ならば pair::first_type を type として提供する。
    // テンプレート引数 I が 1 ならば pair::second_type を type として提供する。
    // それ以外の場合はコンパイルエラーとなる。
    template<size_t I, class Pair> class tuple_element; // 未定義
    template<class T1, class T2> struct tuple_element<0, pair<T1, T2>>;
    template<class T1, class T2> struct tuple_element<1, pair<T1, T2>>;
    // 静的メンバ定数 static size_t value = 2 を提供する。
    template<class Pair> class tuple_size; // 未定義
    template<class T1, class T2> struct tuple_size<pair<T1, T2>>;
  • 下記のフリー関数が定義された。

    // テンプレート引数 I が 0 ならば p.first を、 1 ならば p.second を取得する。
    // それ以外の場合はコンパイルエラーとなる。
    template<size_t I, class T1, class T2>
    typename tuple_element<I, pair<T1, T2>>::type& get(pair<T1, T2>& p) noexcept;
    template<size_t I, class T1, class T2>
    const typename tuple_element<I, pair<T1, T2>>::type& get(
        const pair<T1, T2>& p) noexcept;
    template<size_t I, class T1, class T2>
    typename tuple_element<I, pair<T1, T2>>::type&& get(pair<T1, T2>&& p) noexcept;
    // value のrvalue参照を返す。
    template<class T> typename remove_reference<T>::type&& move(T&& value) noexcept;
    // 例外を送出せずムーブできる場合は move(value) を返す。
    // そうでなければ value の const 参照を返す。
    template<class T>
    typename conditional<
        !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
        const T&,
        T&&>::type
    move_if_noexcept(T& value) noexcept;
    // 関数テンプレート内で引数のlvalue参照/rvalue参照を他の関数に渡す際に用いる。
    template<class T> T&& forward(typename remove_reference<T>::type& value) noexcept;
    template<class T> T&& forward(typename remove_reference<T>::type&& value) noexcept;
    // 型 T のインスタンスを用いて型を得るためのヘルパ関数。
    // 評価されない式(主に sizeof や decltype の引数)の中で用いる。
    // 実際に評価される呼び出しを行うとコンパイルエラーとなる。
    template<class T> typename add_rvalue_reference<T>::type declval() noexcept;
    
    // 例: decltype(a + declval<T>()) value = check() ? (a + t1) : (a + t2);
    
  • 定数 piecewise_construct とその型 piecewise_construct_t が定義された。
    pair クラステンプレートの新しいコンストラクタで第1引数に渡す。

  • フリー関数 swap<algorithm> から移動され、定義が変更された。

    // C++03 in <algorithm>
    template<class T> void swap(T& a, T& b);
    // C++11
    
    // 引数型依存の noexcept 指定
    template<class T> void swap(T& a, T& b)
        noexcept(
            is_nothrow_move_constructible<T>::value &&
            is_nothrow_move_assignable<T>::value);
    
    // 組み込み配列用オーバロード
    template<class T, size_t N> void swap(T (&a)[N], T (&b)[N])
        noexcept(noexcept(swap(*a, *b)));
  • フリー関数 swappair クラステンプレート用オーバロードが定義された。

    template<class T1, class T2>
    void swap(pair<T1, T2>& a, pair<T1, T2>& b) noexcept(noexcept(a.swap(b)));
  • フリー関数 make_pair の定義が変更された。

    // C++03
    template<class T1, class T2>
    pair<T1, T2> make_pair(T1 first, T2 second);
    // C++11
    // 引数が T1, T2 から T1&&, T2&& に変更
    // 戻り値の要素型が変更(詳細後述)
    template<class T1, class T2>
    pair<R1, R2> make_pair(T1&& first, T2&& second);

    上記の型 R1 および R2 は、引数の型 T1 および T2 から下記のように定まる。(参考コンパイラ:gcc-4.8.1)

    // テンプレート引数が reference_wrapper<T> ならば T& を type として提供し、
    // そうでなければテンプレート引数型そのものを type として提供する。
    template<class T> __strip_reference_wrapper { typedef T type; }
    template<class T>
    __strip_reference_wrapper<reference_wrapper<T>> { typedef T& type; }
    template<class T>
    __strip_reference_wrapper<const reference_wrapper<T>> { typedef T& type; }
    
    typedef typename __strip_reference_wrapper<typename decay<T1>::type>::type R1;
    typedef typename __strip_reference_wrapper<typename decay<T2>::type>::type R2;