C++ std :: transform of pairs-> first to new vector

jus*_*tik 19 c++ transform vector functor std-pair

对不起有点初学者的问题.有矢量和矢量对

typedef std::vector <int> TItems;
typedef std::vector < std::pair <int, int> > TPairs;
Run Code Online (Sandbox Code Playgroud)

有没有办法在一步中将对中的所有第一项转换为另一个向量

int main ()
{
TItems items;
TPairs pairs;

pairs.push_back (std::make_pair(1,3));
pairs.push_back (std::make_pair(5,7));

std::transform( items.begin(), items.end(), items.begin(), comp ( &pairs ) );

return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何设计仿函数?

class comp
{
private:
     TPairs *pairs;

public:
    comp ( TPairs  *pairs_ ) : pairs ( pairs_) { }

    unsigned int operator () ( const unsigned int index ) const
    {
        return  (*pairs)[index].second != pairs->end();  //Bad idea
    }
};
Run Code Online (Sandbox Code Playgroud)

也许有一些没有lambda表达式和循环的用户友好方法.谢谢你的帮助.

Fre*_*abe 19

首先,您应该使用a back_inserter作为第三个参数,transform以便将转换后的值推送到向量的后面.

其次,你需要某种类型的函数,它需要一对int并返回第一个.这应该做:

int firstElement( const std::pair<int, int> &p ) {
    return p.first;
}
Run Code Online (Sandbox Code Playgroud)

现在,把各个部分放在一起:

TPairs pairs;
pairs.push_back( std::make_pair( 1, 3 ) );
pairs.push_back( std::make_pair( 5, 7 ) );

TItems items;
std::transform( pairs.begin(), pairs.end(), std::back_inserter( items ),
                firstElement );
Run Code Online (Sandbox Code Playgroud)

在此代码之后,items包含1和5.

  • 是否有任何聪明的方法来使用[std :: get <0>](http://en.cppreference.com/w/cpp/utility/tuple/get)而不是自定义函数? (2认同)

ste*_*anv 13

请参阅frerich或kotlinski对C++ 03的回答.

使用lambda的C++ 11解决方案:

std::transform(pairs.begin(), 
               pairs.end(), 
               std::back_inserter(items), 
               [](const std::pair<int, int>& p) { return p.first; });
Run Code Online (Sandbox Code Playgroud)


NHD*_*aly 8

我真的希望你std::get用作函子,因为它已经作为库函数提供了!

如果我们能写出这条线,那会不会很棒!?

std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
Run Code Online (Sandbox Code Playgroud)

......但它比那更可怕.您需要消除get使用哪个歧义:

int main() {
  std::vector<int> items;
  std::vector<std::pair<int, int>> pairs;

  pairs.push_back(std::make_pair(1, 3));
  pairs.push_back(std::make_pair(5, 7));

  std::transform(pairs.begin(), pairs.end(), std::back_inserter(items),
                 (const int& (*)(const std::pair<int, int>&))std::get<0>);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是,std::get 重载是将1. pair&,2 const pair&.和3. pair&&作为参数,以便它可以作为输入用于任何种类的对.不幸的是,重载会妨碍模板类型推导std::transform,因此我们的原始行

std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
Run Code Online (Sandbox Code Playgroud)

产量

 error: no matching function for call to ‘transform(std::vector<std::pair<int, int> >::iterator, std::vector<std::pair<int, int> >::iterator, std::back_insert_iterator<std::vector<int> >, <unresolved overloaded function type>)’
   std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
                                                                                    ^
...

/usr/include/c++/4.8/bits/stl_algo.h:4915:5: note:   template argument deduction/substitution failed:
 note:   couldn't deduce template parameter ‘_UnaryOperation’
   std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
Run Code Online (Sandbox Code Playgroud)

std::get在推导模板时,它不知道您要求哪个超载std::transform,因此您必须手动指定它.将函数指针强制转换为正确的类型告诉编译器,"嘿,请使用get带有a 的重载const&并返回一个const&!"

但至少我们正在使用标准库组件(yay)?

就行数而言,它并不比其他选项更糟糕:http: //ideone.com/6dfzxz