std::forward_list (c++11)

std::forward_list を試してみます。

 

 

 

std::forward_list
ヘッダ <forward_list> で定義
template<
    class T,
    class Allocator = std::allocator<T>
> class forward_list;
(1)(c++11以上)
namespace pmr {
    template <class T>
    using forward_list = std::forward_list<T, std::pmr::polymorphic_allocator<T>>;
}
(2)(c++17以上)
テンプレート引数
T - 要素の型
Allocator - メモリを確保/解放したり、そのメモリに要素を構築/破棄したりするために使用されるアロケータ。 この型は Allocator の要件を満たさなければなりません。 Allocator::value_type と T が同じでない場合、動作は未定義です。

 

std::forward_list はコンテナ内のあらゆる位置への高速な挿入と削除をサポートするコンテナです。高速なランダムアクセスはサポートされません。このコンテナは片方向連結リストとして実装され、本質的に C で実装された場合と比較していかなるオーバーヘッドもありません。std::listと比較すると、このコンテナは双方向のイテレーションが必要ないため、より空間効率の良い記憶領域を提供します。

リスト内の要素を追加、削除、移動、またはいくつかのリストを横断するそれらの操作は、リスト中の他の要素を現在参照しているイテレータを無効化しません。しかし、(erase_afterを用いて)リストから要素が削除される場合、対応する要素を参照するイテレータや参照は無効化されます。

std::forward_list は(size メンバ関数と operator== の計算量が常に線形時間であることを除いて) Container, AllocatorAwareContainer, SequenceContainer の要件を満たします。

 

 

1. 始めに - Constructor

[概要]

forward_list の各種コンストラクタの例を示します。

 

[環境]

コンパイラ : g++, 9.3.0
OS : Ubuntu (WSL2), 20.04

 

[プログラムソース "forword_list_01.cpp"]

#include <forward_list> // forward_list
#include <string>   // string
#include <iostream> // ostream

template<typename T>
std::ostream& operator<<(std::ostream& os, const std::forward_list<T>& v)
{
    os.put('[');
    char comma[3] = {'\0', ' ', '\0'};
    for (const auto& e : v){
        os << comma << e;
        comma[0] = ',';
    }
    return os << ']';
}

int main()
{
    // c++11 の初期化リストの構文
    std::forward_list<std::string> words1 {"the", "frogurt", "is", "also", "cursed."};
    std::cout << "words1: " << words1 << std::endl;

    // word2 = word1
    std::forward_list<std::string> words2(words1.begin(), words1.end());
    std::cout << "words2: " << words2 << std::endl;

    // words3 = words1
    std::forward_list<std::string> words3(words1);
    std::cout << "words3: " << words3 << std::endl;

    // words4 is {"Mo","Mo", "Mo", "Mo", "Mo"}
    std::forward_list<std::string> words4(5, "Mo");
    std::cout << "words4: " << words4 << std::endl;

    return EXIT_SUCCESS;
}

 

[出力]

words1: [the, frogurt, is, also, cursed.]
words2: [the, frogurt, is, also, cursed.]
words3: [the, frogurt, is, also, cursed.]
words4: [Mo, Mo, Mo, Mo, Mo]

 

 

2. 挿入

[概要]

挿入系のメソッドをいろいろと試してみます。

 

[環境]

コンパイラ : g++, 9.3.0
OS : Ubuntu (WSL2), 20.04

 

[プログラムソース "forward_list_02.cpp"]

#include <forward_list> // forward_list
#include <string>   // string
#include <iostream> // ostream

template<typename T>
std::ostream& operator<<(std::ostream& os, const std::forward_list<T>& v)
{
    os.put('[');
    char comma[3] = {'\0', ' ', '\0'};
    for (const auto& e : v){
        os << comma << e;
        comma[0] = ',';
    }
    return os << ']';
}

int main(){
    // c++11 の初期化リストの構文
    std::forward_list<std::string> words1 {"1", "2", "3", "4", "5"};
    std::cout << "words1: " << words1 << std::endl;

    // emplace_front
    words1.emplace_front("emplace_front");
    std::cout << "words1: " << words1 << std::endl;

    // push_front
    words1.push_front(std::string("push_front"));
    std::cout << "words1: " << words1 << std::endl;

    // emplace_after
    words1.emplace_after(words1.begin(), "emplace_after");
    std::cout << "words1: " << words1 << std::endl;

    // insert_after
    words1.insert_after(words1.begin(), std::string("insert_after"));
    std::cout << "words1: " << words1 << std::endl;

    // insert_afert & next
    std::forward_list<std::string> li {"test1", "test2", "test3"};
    words1.insert_after(std::next(words1.begin(), 3), li.begin(), li.end());
    std::cout << "words1: " << words1 << std::endl;

    // insert_after & prev
    // forward_list で prev() を使用することはできません。コンパイルは成功しますが実行時に例外を送出します。
#if 0
    std::forward_list<std::string> fi {"test1", "test2", "test3"};
    words1.insert_after(std::prev(words1.end(), 3), fi.begin(), fi.end());
    std::cout << "words1: " << words1 << std::endl;
#endif

    return EXIT_SUCCESS;
}

[出力]
words1: [1, 2, 3, 4, 5]
words1: [emplace_front, 1, 2, 3, 4, 5]
words1: [push_front, emplace_front, 1, 2, 3, 4, 5]
words1: [push_front, emplace_after, emplace_front, 1, 2, 3, 4, 5]
words1: [push_front, insert_after, emplace_after, emplace_front, 1, 2, 3, 4, 5]
words1: [push_front, insert_after, emplace_after, emplace_front, test1, test2, test3, 1, 2, 3, 4, 5]

 

 

ライセンス

本ページの情報は、特記無い限り下記 MIT ライセンスで提供されます。

The MIT License (MIT)

  Copyright 2021 Kinoshita Hidetoshi

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 

 

参考

 


 

変更履歴

2025-03-03 - ページデザイン更新
2021-01-03 - 新規作成

 

Programming Items トップページ

プライバシーポリシー