I will start from code:
#include <iostream>
#include <vector>
using namespace std;
struct A
{
int color;
A(int p_f) : field(p_f) {}
};
int main ()
{
A la[4] = {A(3),A(5),A(2),A(1)};
std::vector<int> lv = {begin(la).color, end(la).color};//I would like to create vector from specific value from array la
for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it) std::cout << ' ' << *it;
return 0;
}
Generally I would like to create a vector from specific values from array. As you can see la is A array and I would like to create vector containing not the whole la array, but only color. vector(int) not vector(A), which vector{3,5,2,1}, so not A, but only int color. It can be done using in C++11 also. Thanks.
This should work.
std::vector<int> lv;
std::transform(std::begin(la), std::end(la), std::back_inserter(lv), [](const A& a){
return a.color;
});
Also here is another way:
Refactor your structure to get color from a method:
struct A
{
int color;
A(int p_f) : color(p_f) {}
int getColor() const {
return color;
}
};
In this case you may use bind
:
std::transform(std::begin(la), std::end(la), std::back_inserter(lv), std::bind(&A::getColor, std::placeholders::_1));
Or you may also use std::mem_fn
to method which is a bit shorter (thanks to @Piotr S.):
std::transform(std::begin(la), std::end(la), std::back_inserter(lv), std::mem_fn(&A::getColor));
Or you may use std::mem_fn
to data member. In this case you don't even need to implement a getter method:
std::transform(std::begin(la), std::end(la), std::back_inserter(lv), std::mem_fn(&A::color));
Following may help:
namespace detail
{
using std::begin;
using std::end;
template <typename Container, typename F>
auto RetrieveTransformation(const Container& c, F f)
-> std::vector<std::decay_t<decltype(f(*begin(c)))>>
{
// if `F` return `const T&`, we want `std::vector<T>`,
// so we remove reference and cv qualifier with `decay_t`.
//
// That handles additionally the case of lambda
// The return type of lambda [](const std::string&s) { return s;}
// - is `const std::string` for msvc
// - is `std::string` for for gcc
// (Note that the return type rules have changed:
// see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1048)
using F_Ret = std::decay_t<decltype(f(*begin(c)))>;
std::vector<F_Ret> res;
res.reserve(std::distance(begin(c), end(c)));
for (const auto& e : c)
{
res.push_back(f(e));
}
return res;
}
}
template <typename Container, typename F>
auto RetrieveTransformation(const Container& c, F f)
-> decltype(detail::RetrieveTransformation(c, f))
{
return detail::RetrieveTransformation(c, f);
}
And then use it as
std::vector<int> lv = RetrieveTransformation(la, std::mem_fn(&A::getColor));
// or
// auto lv = RetrieveTransformation(la, [](const A&a){return a.color;});
Live Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With