2015-06-17 21 views
4

我将从码开始:如何从数组的特定值创建向量?

#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; 
} 

一般来说,我想创建从阵列特定值的向量。 正如你所看到的,la是一个数组,我想创建一个不包含整个la数组但只包含颜色的矢量。 vector(int)不是矢量(A),哪个矢量{3,5,2,1},所以不是A,而只是int的颜色。它也可以在C++ 11中使用。谢谢。

回答

10

这应该工作。

std::vector<int> lv; 
std::transform(std::begin(la), std::end(la), std::back_inserter(lv), [](const A& a){ 
    return a.color; 
}); 

而且,这里是另一种方式:

重构你的结构从方法得到的颜色:

struct A 
{ 
    int color; 

    A(int p_f) : color(p_f) {} 

    int getColor() const { 
     return color; 
    } 
}; 

在这种情况下,你可以使用bind

std::transform(std::begin(la), std::end(la), std::back_inserter(lv), std::bind(&A::getColor, std::placeholders::_1)); 

或者您也可以使用std::mem_fn来缩短这个方法(感谢@Piotr S.):

std::transform(std::begin(la), std::end(la), std::back_inserter(lv), std::mem_fn(&A::getColor)); 

或者你可以使用std::mem_fn数据成员。在这种情况下,你甚至都不需要实现一个getter方法:

std::transform(std::begin(la), std::end(la), std::back_inserter(lv), std::mem_fn(&A::color)); 
+3

' std :: mem_fn(&A :: getColor)'代替'bind'也可以做到这一点,它也适用于数据成员 –

+0

@P iotrS。好的一点。 –

1

以下可能会有所帮助:

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); 
} 

,然后用它作为

std::vector<int> lv = RetrieveTransformation(la, std::mem_fn(&A::getColor)); 
// or 
// auto lv = RetrieveTransformation(la, [](const A&a){return a.color;}); 

Live Demo

相关问题