読者です 読者をやめる 読者になる 読者になる

変換後コンテナを返すtransform

コンテナの全ての要素に変換をかけ、変換後のコンテナをそのままループ処理したい

つまり、C# 3.0でできるこの処理をC++でやりたい

List<int> ar = new List<int>{3, 1, 4};

foreach (string str in ar.ConvertAll(x => x.ToString()))
    Console.WriteLine(str);

結果からいうと、こういうコードが書けるようになった

#include <iostream>
#include <string>
#include <sstream>
#include <shand/foreach.hpp>
#include <shand/algorithm.hpp>

using namespace std;
using namespace shand;

std::string to_string(int value)
{
    std::stringstream interpreter;
    interpreter << value;
    return interpreter.str();
}

int main()
{
    vector<int> v;

    v.push_back(3);
    v.push_back(1);
    v.push_back(4);

    foreach(const string& value, transform(v, to_string))
        cout << value << endl;

    return 0;
}

まず、前提条件としてTR1のresult_ofが必要になる
(変換関数の戻り値の型が必要なので)

それと、以前私が作ったRange STLアルゴリズムのtransformが必要


以下がその実装

template <class Container>
struct range_value {
    typedef typename Container::value_type type;
};

template <class Type, int Size>
struct range_value<Type[Size]> {
    typedef Type type;
};

template <class Type, int Size>
struct range_value<const Type[Size]> {
    typedef Type type;
};

template <class Container, class UnaryOperation>
std::vector<typename std::tr1::result_of<UnaryOperation(typename range_value<Container>::type)>::type>
transform(const Container& c, UnaryOperation op)
{
    typedef typename std::tr1::result_of<UnaryOperation(typename range_value<Container>::type)>::type value_type;

    std::vector<value_type> v;
    shand::transform(c, std::back_inserter(v), op);
    return v;
}

ライブラリまとめ