• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    function
    <memory_resource>

    std::pmr::polymorphic_allocator::construct

    template <class T, class... Args>
    void construct(T* p, Args&&... args);                   //(1)
    
    template <class T1, class T2, class... Args1, class... Args2>
    void construct(pair<T1, T2>* p, piecewise_construct_t,
                   tuple<Args1...> x, tuple<Args2...> y);   //(2) C++17 まで
    
    template <class T1, class T2>
    void construct(pair<T1, T2>* p);                        //(3) C++17 まで
    
    template <class T1, class T2, class U, class V>
    void construct(pair<T1, T2>* p, U&& x, V&& y);          //(4) C++17 まで
    
    template <class T1, class T2, class U, class V>
    void construct(pair<T1, T2>* p, const pair<U, V>& pr);  //(5) C++17 まで
    
    template <class T1, class T2, class U, class V>
    void construct(pair<T1, T2>* p, pair<U, V>&& pr);       //(6) C++17 まで
    

    概要

    p で指定された領域に、*this と指定された引数で uses-allocator 構築を行う。
    また、*ppair だった場合は、それぞれの要素に対して *this と指定された引数で uses-allocator 構築を行う。

    適格要件

    • (1) : *thisargs... をコンストラクタ引数とした uses-allocator 構築が可能であること。
      アロケータを受け取るコンストラクタを持たない型については、(args.. が適切ならば)この要件を常に満たしている。
      C++17までは、この関数は Tpair の特殊化でない場合に限りオーバーロード解決に参加する。

    引数

    • 全て : p -- T もしくは pair<T1, T2> のオブジェクトを構築するメモリ領域へのポインタ

    • (1) : args -- T のコンストラクタに渡す引数列

    • (2) :

      • x -- T1 のコンストラクタに渡す引数を持つ tuple オブジェクト
      • y -- T2 のコンストラクタに渡す引数を持つ tuple オブジェクト
    • (4) :

      • x -- T1 のコンストラクタに渡す引数
      • y -- T2 のコンストラクタに渡す引数
    • (5) : pr -- T1, T2 のコンストラクタにそれぞれコピーして渡す引数 U, V のオブジェクトを持つ pair<U, V>オブジェクト

    • (6) : pr -- T1, T2 のコンストラクタにそれぞれ forward して渡す引数 U, V のオブジェクトを持つ pair<U, V> オブジェクト

    効果

    例外

    • (1) : Tのコンストラクタが例外を投げないならば、この関数も例外を投げない。

    備考

    • C++20 における変更は、一見新規導入されたユーティリティ関数(uninitialized_construct_using_allocator)を使用して定義を簡略化しただけのように思えるが、実はこの変更によりネストした pair に対しても uses-allocator 構築がサポートされるように改善されている。

    (1)の例

    #include <iostream>
    #include <memory_resource>
    
    int main()
    {
      std::pmr::polymorphic_allocator<int> alloc{};
    
      //メモリの確保
      int* array = alloc.allocate(4);
    
      //要素を構築
      for (int i = 0; i < 4; ++i) {
        alloc.construct(array + i, i);
      }
    
      for (int i = 0; i < 4; ++i) {
        std::cout << array[i] << std::endl;
      }
    
      //要素を破棄
      for (int i = 0; i < 4; ++i) {
        alloc.destroy(array + i);
      }
    
      //メモリの解放
      alloc.deallocate(array, 4);
    }
    

    出力

    0
    1
    2
    3
    

    pair関連のオーバーロードの例

    #include <iostream>
    #include <memory_resource>
    #include <string>
    #include <tuple>
    #include <utility>
    
    int main()
    {
      //intとpolymorphic_allocatorを用いるstringのpair
      using pair = std::pair<int, std::pmr::string>;
    
      //memory_resourceとしてmonotonic_buffer_resourceを使用
      auto mr = std::pmr::monotonic_buffer_resource{};
      std::pmr::polymorphic_allocator<pair> alloc{&mr};
    
      std::cout << std::boolalpha;
      std::cout << "(2)" << std::endl;
    
      //(2)
      {
        pair* p = alloc.allocate(1);
    
        alloc.construct(p, std::piecewise_construct
            , std::make_tuple(128)         //intを128で初期化
            , std::make_tuple("string", 3) //string("string", 3)で初期化(最初の3文字を保持する)
        );
    
        std::cout << p->first << std::endl;
        std::cout << p->second << std::endl;
        //アロケータが伝播している
        std::cout << (p->second.get_allocator() == alloc) << std::endl;
      }
    
      std::cout << "\n(3)" << std::endl;
    
      //(3)
      {
        pair* p = alloc.allocate(1);
    
        alloc.construct(p);  //両要素をデフォルト構築
    
        std::cout << p->first << std::endl;
        std::cout << p->second << std::endl;
        //アロケータが伝播している
        std::cout << (p->second.get_allocator() == alloc) << std::endl;
      }
    
      std::cout << "\n(4)" << std::endl;
    
      //(4)
      {
        pair* p = alloc.allocate(1);
    
        alloc.construct(p, 128, "string");  //両要素をこれらの値からムーブ構築
    
        std::cout << p->first << std::endl;
        std::cout << p->second << std::endl;
        //アロケータが伝播している
        std::cout << (p->second.get_allocator() == alloc) << std::endl;
      }
    
      std::cout << "\n(5)" << std::endl;
    
      //(5)
      {
        pair* p = alloc.allocate(1);
    
        const auto v = std::make_pair(128, "copy");
        alloc.construct(p, v);  //両要素を変換可能なpairからコピー構築
    
        std::cout << p->first << std::endl;
        std::cout << p->second << std::endl;
        //アロケータが伝播している
        std::cout << (p->second.get_allocator() == alloc) << std::endl;
      }
    
      std::cout << "\n(6)" << std::endl;
    
      //(6)
      {
        pair* p = alloc.allocate(1);
    
        alloc.construct(p, std::make_pair(128, "move"));  //両要素を変換可能なpairからムーブ構築
    
        std::cout << p->first << std::endl;
        std::cout << p->second << std::endl;
        //アロケータが伝播している
        std::cout << (p->second.get_allocator() == alloc) << std::endl;
      }
    }
    

    出力

    (2)
    128
    str
    true
    
    (3)
    0
    
    true
    
    (4)
    128
    string
    true
    
    (5)
    128
    copy
    true
    
    (6)
    128
    move
    true
    

    ネストした pair の例

    #include <iostream>
    #include <string>
    #include <utility>
    #include <memory_resource>
    
    int main()
    {
      using pair = std::pair<std::pair<int, std::pmr::string>, std::pmr::string>;
    
      auto mr = std::pmr::monotonic_buffer_resource{};
      std::pmr::polymorphic_allocator<pair> alloc{&mr};
    
      std::cout << std::boolalpha;
    
      pair* p = alloc.allocate(1);
    
      alloc.construct(p);
    
      std::cout << (p->first.second.get_allocator() == alloc) << '\n';
      std::cout << (p->second.get_allocator() == alloc) << '\n';
    
      alloc.destroy(p);
    
      alloc.deallocate(p, 1);
    }
    

    C++17 における出力

    false
    true
    

    C++20 における出力

    true
    true
    

    バージョン

    言語

    • C++17

    処理系

    関連項目

    参照