Create a container from another container, applying each element to a function in C ++

My question is simple, see example:

std::array<int,6> a = {{0,1,2,3,4,5}}; // -- given container.
auto F = []( int i ) { return  i*i; }; // -- given function.

std::vector<int> v;  // need create

// my solution:
v.reserve( a.size () );
for( std::size_t i = 0; i < a.size(); ++i )
    v.push_back( F(a[i]) ); 



// but I need something like
   std::vector<int>v( a.begin(), a.end(), <|applying each element to F|> );

Is it possible to create a container something like the above without explicitly invoking the kernel and any redistribution?

EDIT :

  • I want to avoid the reserve; because othercase my first decision is good for me :)
  • I want to avoid resizing; because it initialized each element by default ctor.
  • I will use this in a real project, which can include many 3 party libraries (boost, Soft-STL, ...).
+4
source share
3 answers

boost::transform_iterator. , . std::back_inserter reserve resize . :

std::vector<int> result(
      boost::make_transform_iterator(std::begin(a), F)
    , boost::make_transform_iterator(std::end(a), F)
    );

terser, :

std::vector<int> result(transform_range(a, F));

transform_range :

template<class Iterator>
struct AutoSequence
{
    Iterator const beg_, end_;

    template<class T>
    operator std::vector<T>() const {
        return {beg_, end_};
    }
};

template<class Function, class InSeq>
auto transform_range(InSeq const& in) -> AutoSequence<decltype(boost::make_transform_iterator<Function>(in.begin()))> {
    return {
          boost::make_transform_iterator<Function>(std::begin(in))
        , boost::make_transform_iterator<Function>(std::end(in))
        };
}

template<class Function, class InSeq>
auto transform_range(InSeq const& in, Function&& f) -> AutoSequence<decltype(boost::make_transform_iterator(in.begin(), f))> {
    return {
          boost::make_transform_iterator(std::begin(in), f)
        , boost::make_transform_iterator(std::end(in), f)
        };
}
+2

std::transform !

std::vector<int> v(a.size());
std::transform(
   std::begin(a), std::end(a),
   std::begin(v),
   F
);

std::back_inserter, :

std::vector<int> v;
std::transform(
   std::begin(a), std::end(a),
   std::back_inserter(v),
   F
);

, ( reserve, ). , .

+9

std::transform:

#include <algorithm> // std::transform
#include <iterator>  // std::back_inserter

....

transform(a.begin(), a.end(), back_inserter(v), F);

v.reserve(asize()), .

+5

Source: https://habr.com/ru/post/1528180/


All Articles