potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C++17 基本的なSTL要素操作

2021/3/10:この記事は別のブログで投稿した記事を移動したものです。

C++17とSTLを用いた基本的な要素操作の方法の覚書です。

コンテナの要素を標準出力へ一括出力する

ostream_iterator、cout/wcout、copyを組み合わせることで配列やコンテナクラス(vector、initializer_list等)の要素を標準出力へ一括出力することができます。以下はinitializer_listの要素を出力する例です。

#include <iostream>
#include <iterator>

int main()
{
    auto values = {1, 2, 3, 4, 5};
    std::ostream_iterator<int, wchar_t> oit(std::wcout, L", ");
    std::copy(values.begin(), values.end(), oit);
    return 0;
}

出力

1, 2, 3, 4, 5, 

コンテナの要素を標準出力へ変形しながら一括出力する

ostream_iterator、cout/wcout、transformを組み合わせることで配列やコンテナクラス(vector、initializer_list等)の要素を標準出力へ変形しながら一括出力することができます。以下はinitializer_listの要素に100を足した値を出力する例です。

#include <algorithm>
#include <iostream>
#include <iterator>

int main()
{
    auto values = {1, 2, 3, 4, 5};
    std::ostream_iterator<int, wchar_t> oit(std::wcout, L", ");
    std::transform(values.begin(), values.end(), oit,
        [](auto x) {return x + 100; });
    return 0;
}

出力

101, 102, 103, 104, 105,

コンテナの条件を満たす要素を別のコンテナ(vector等)にコピーする

initializer_listの要素から奇数のみコピーしたvectorを作成

copy_if、front_inserter/back_inserter/inserterを組み合わせることで配列やコンテナクラス(vector、initializer_list等)の条件を満たす要素を別のコンテナにコピーすることができます。以下はinitializer_listの要素から奇数のみコピーしたvectorを作成します。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
    auto values1 = {1, 2, 3, 4, 5};
    std::vector<int> values2;
    std::copy_if(values1.begin(), values1.end(), std::back_inserter(values2),
        [](auto x) {return (x % 2) != 0; });

    std::ostream_iterator<int, wchar_t> oit(std::wcout, L", ");
    std::copy(values2.begin(), values2.end(), oit);
    return 0;
}

出力例

1, 3, 5,

文字列からアルファベットの小文字部分のみ抜き出した文字列を作成する

#include <algorithm>
#include <iostream>

int main()
{
    std::wstring s1 = L"aBCdEfghI";
    std::wstring s2;
    std::copy_if(s1.begin(), s1.end(), std::back_inserter(s2), iswlower);

    std::wcout << s2 << std::endl;

    return 0;
}

出力例

adfgh

vectorからmapを作成する

transform、inserterを組み合わせることでvectorからmapを作成することができます。mapはinsertメソッドを提供しているため、inserterのみ使用することができます(back_inserterやfront_inserterは使用できません)。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <string>

int main()
{
    auto values1 = {1, 2, 3, 4, 5};
    std::map<int, int> map1;
    std::transform(values1.begin(), values1.end(), std::inserter(map1, map1.end()),
        [](auto x) {return std::make_pair(x, x + 100); });

    std::ostream_iterator<std::wstring, wchar_t> oit(std::wcout, L"\r\n");
    std::transform(map1.begin(), map1.end(), oit,
        [](std::pair<int, int> pair) {
            std::wstring buf(std::to_wstring(pair.first));
            buf += L", ";
            buf += std::to_wstring(pair.second);
            return buf;
        });
    return 0;
}

出力例

1, 101
2, 102
3, 103
4, 104
5, 105

その他

Visual Studio 2019のC++プロジェクトでC++17を有効化する

以下の手順でC++17を有効にすることができます。 + プロジェクトのプロパティを開く + 構成プロパティ→C/C++→言語を開く + 「C++ 言語標準」を「ISO C++17 標準 (/std:c++17)」に設定する