C++ の list にある splice 関数はリストの切り貼りの関数2020年02月29日 14時05分26秒

C++ の list の中にある splice 関数はリストを切り貼りする関数。std::list は双方向リストなので、この切り貼り関数の処理は高速。良く眼にする使い方は、一つのリストからもう一つのリストへの全移動。vector 等と違って高速。スレッドプールなどの実装に使うのにも都合が良い。また、珍しくなるが、一つのリストを切り貼りして順序を入れ換えたりするのにも使える。

この splice の引数はこんがりやすい。特に、イテレータを三つも取ったりするので、何処から何処に動かしたいのか一目では分かりづらい。

#include <list>
#include <iostream>
#include <algorithm>

int main()
{
    auto p = []( int i ){ std::cout << i << ' '; };

    std::list< int > ones = { 1, 2, 3, 4, 5 };
    std::list< int > tens = { 10, 12, 13, 14, 15 };

    auto itr = ones.begin();
    std::advance( itr, 3 );

    ones.splice( ones.begin(), ones, itr, ones.end() );

    std::cout << "ones " << "[ ";
    std::for_each( ones.begin(), ones.end(), p );

    tens.splice( tens.begin(), ones );

    std::cout << "]\nones " << "[ ";
    std::for_each( ones.begin(), ones.end(), p );
    std::cout << "]\ntens " << "[ ";
    std::for_each( tens.begin(), tens.end(), p );
    std::cout << ']' << std::endl;
}
この例では、最初は一桁の数字の前後を入れ換えている。その後、二桁の数字の列の前に挿入している。

splice 自体は、c++03 からあったが、list の内容を表示するのにラムダ関数と、std::for_each を使っているので、コンパイルには C++11 以上が必要。

% c++ -std=c++11 splice.cpp
% ./a.out 
ones [ 4 5 1 2 3 ]
ones [ ]
tens [ 4 5 1 2 3 10 12 13 14 15 ]
% 
出力は、こんな感じになる。