C++ C++;std::成对的变换向量->;先到新向量
对不起,有一点初学者的问题。有向量和向量对C++ C++;std::成对的变换向量->;先到新向量,c++,vector,transform,functor,std-pair,C++,Vector,Transform,Functor,Std Pair,对不起,有一点初学者的问题。有向量和向量对 typedef std::vector <int> TItems; typedef std::vector < std::pair <int, int> > TPairs; 如何设计函子 class comp { private: TPairs *pairs; public: comp ( TPairs *pairs_ ) : pairs ( pairs_) { } unsigned
typedef std::vector <int> TItems;
typedef std::vector < std::pair <int, int> > TPairs;
如何设计函子
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
}
};
也许有一些没有lambda表达式和循环的更用户友好的方法。谢谢你的帮助。这个怎么样
items.reserve(pairs.size());
for (size_t it = 0; it < pairs.size(); ++it) {
items.push_back(pairs[it].first);
}
items.reserve(pairs.size());
for(size_t it=0;it
易于理解和调试。首先,应使用a作为第三个参数,以便将转换后的值推送到向量的后面 其次,需要某种函子,它接受一对整数并返回第一个整数。这应该做到:
int firstElement( const std::pair<int, int> &p ) {
return p.first;
}
在此代码之后,
项包含1和5。使用std::bind如何
std::transform(pairs.begin(),
pairs.end(),
std::back_inserter(items),
std::bind(&TPairs::value_type::first, std::placeholders::_1));
(对于非C++11代码,用boost::bind
替换std::bind
)参见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; });
std::transform(pairs.begin(),
pairs.end(),
标准:背面插入器(项目),
[](const std::pair&p){return p.first;});
我真的希望您使用std::get
作为functor,因为它已经作为库函数提供了
如果我们能写这句话岂不是太好了
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
问题是,std::get
取1<代码>配对&
,2<代码>常量对&,和3pair&&
作为参数,因此它可以作为输入用于任何类型的pair。不幸的是,重载妨碍了std::transform
的模板类型推断,因此我们的原始行
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
std::transform(pairs.begin()、pairs.end()、std::back\u插入器(items)、std::get);
屈服
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>);
错误:调用“transform(std::vector::iterator,std::vector::iterator,std::back\u insert\u iterator,)时没有匹配的函数”
std::transform(pairs.begin()、pairs.end()、std::back\u插入器(items)、std::get);
^
...
/usr/include/c++/4.8/bits/stl_algo.h:4915:5:注意:模板参数推导/替换失败:
注意:无法推断模板参数“\u UnaryOperation”
std::transform(pairs.begin()、pairs.end()、std::back\u插入器(items)、std::get);
在为std::transform
推导模板时,它不知道您需要哪个std::get
重载,因此您必须手动指定它。将函数指针投射到正确的类型会告诉编译器,“嘿,请使用重载,get
获取一个const&
并返回一个const&
!”
但至少我们使用的是标准库组件(yay)
就行数而言,它并不比其他选项差:
C++11的另一种可能性是,这与使用
std::bind的解决方案类似:
std::transform(pairs.begin(),
pairs.end(),
std::back_inserter(items),
std::mem_fn(&std::pair<int,int>::first)
);
std::transform(pairs.begin(),
pairs.end(),
标准:背面插入器(项目),
std::mem_fn(&std::pair::first)
);
@kotlinski:谢谢,但这是一个常见的解决方案。我想找到一个没有任何循环的一步解决方案,如果可能的话,你需要一些用户友好的,那么这将是误导性的答复与一些C++的暴行:+ 1:在这种情况下最简单。如果循环简化,为什么要避免循环?@stefaanv:因为OP明确要求回答没有lambda表达式和循环。
@Frerich:我的“为什么”实际上指的是这个限制,但我承认这并不清楚。哎呀,我没有注意到“没有lambda”的要求,但是为什么当它是直截了当的,并且是语言的一部分时,我相信它不是C++语言的一部分,大多数人都可以使用(无论是由于编译器的限制还是因为工作场所的某些要求)。有没有使用自定义函数的巧妙方法?有人能想到什么改进吗?能够像这样干净地使用std::get
,那就太好了。。。实际上,我可能应该使用reinterperet_cast(std::get)
,但这似乎更糟……我认为可以用包装在lambda中的get函数替换“硬”cast,可以为其指定参数
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
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>);
std::transform(pairs.begin(),
pairs.end(),
std::back_inserter(items),
std::mem_fn(&std::pair<int,int>::first)
);