変更を行う STLアルゴリズム 解答ページ | Programming Place Plus C++編【標準ライブラリ】 第20章

トップページC++編

C++編で扱っている C++ は 2003年に登場した C++03 という、とても古いバージョンのものです。C++ はその後、C++11 -> C++14 -> C++17 -> C++20 と更新されており、今後も 3年ごとに更新されます。
なかでも C++11 での更新は非常に大きなものであり、これから C++ の学習を始めるのなら、C++11 よりも古いバージョンを対象にするべきではありません。特に事情がないなら、新しい C++ を学んでください。 当サイトでは、C++14 をベースにした新C++編を作成中です。

問題①

問題① fill/fill_n と generate/generate_n について、その違いを説明してください。


fill/fill_n も、generate/generate_n も、指定の範囲内の要素全体に値を書き込む関数です。指定された範囲内の要素は、すべて無条件で書き込みの対象になります。

fill系は、指定した値をそのまま代入するだけであるのに対し、generate系は、書き込む値を、関数や関数オブジェクトを使って指定できるという点が大きな違いになります。

generate系は、1つの値を書き込むたびに、関数や関数オブジェクトを呼び出して値を生成します。そのため、各要素に同じ値を書き込むことも、異なる値を書き込むことも可能です(同じ値で良いのなら、generate関数の外部で値を生成させて、その値を fill関数に渡した方が効率的です)。

問題②

問題② copy関数がどのように実装されているか、想像して自力の実装を書いてみてください。


次のような感じになるはずです。

template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
{
    while (first != last) {
        *result = *first;
        ++result;
        ++first;
    }
    return result;
}

インクリメントを代入のところでまとめて行うなど、さらに短く書くことはできますが、意味としては変わりはありません。

なお、first と last は、入力イテレータであるため、while文の条件式には「!=」か「==」しか使えないことに注意してください(第14章)。

問題③

問題③ 正負が混じった int型の値が格納された std::list があるとき、すべての要素の符号を反転させる処理を STLアルゴリズムを使って記述してください。


コンテナ間で要素をコピーするのではなく、自身の値を変更したい場合は、transform関数を使用できます。

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

namespace {
    int ChangeSign(int elem)
    {
        return -elem;
    }

    void Println(int elem)
    {
        std::cout << elem << std::endl;
    }
}

int main()
{
    std::list<int> lst;
    lst.push_back(0);
    lst.push_back(-1);
    lst.push_back(2);
    lst.push_back(3);
    lst.push_back(-4);

    std::transform(lst.begin(), lst.end(), lst.begin(), ChangeSign);
    std::for_each(lst.begin(), lst.end(), Println);
}

実行結果

0
1
-2
-3
4


参考リンク


更新履歴

’2016/11/23 新規作成。



第20章のメインページへ

C++編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る