C++ std::transform 成对向量 -> 第一个到新向量
抱歉,有一点初学者问题。有向量和对向量
typedef std::vector <int> TItems;
typedef std::vector < std::pair <int, int> > TPairs;
有没有办法一步将所有第一个项目对转换为另一个向量
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;
}
如何设计函子?
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 表达式和循环。感谢您的帮助。
Sorry for a little bit beginner question. There are vector and vector of pairs
typedef std::vector <int> TItems;
typedef std::vector < std::pair <int, int> > TPairs;
Is there any way to transform all first items in pair to another vector in one step
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;
}
How to design a functor?
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
}
};
Maybe there is some more user friendly method without lambda expressions and loops. Thanks for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
首先,您应该使用
back_inserter
作为transform
的第三个参数,以便转换后的值被推到向量的后面。其次,您需要某种函子,它接受一对整数并返回第一个整数。应该这样做:
现在,将各个部分放在一起:
在此代码之后,
items
包含 1 和 5。First of all, you should use a
back_inserter
as the third argument totransform
so that the transformed values are pushed to the back of the vector.Second, you need some sort of functor which takes a pair of ints and returns the first one. This should do:
Now, to put the pieces together:
After this code,
items
contains 1 and 5.请参阅 frerich 或 kotlinski 对 C++03 的回答。
使用 lambda 的 C++11 解决方案:
see frerich's or kotlinski's answer for C++03.
C++11 solution with lambda:
我真的希望您使用 std::get 作为函子,因为它已经作为库函数提供了!
如果我们能写出这一行岂不是很好!?
……但比这更可怕一点。您需要消除要使用的
get
的歧义:问题是
std::get
重载以获取 1.pair&
、2.constpair&
和 3.pair&&
作为参数,以便它适用于任何类型的对作为输入。不幸的是,重载妨碍了std::transform
的模板类型推导,因此我们的原始行产生
It 不知道
std::get
的哪个重载您在推导std::transform
模板时要求,因此您必须手动指定它。将函数指针转换为正确的类型告诉编译器,“嘿,请使用重载,其中get
接受const&
并返回const&
>!”但至少我们正在使用标准库组件(是的)?
就行数而言,它并不比其他选项差:
http://ideone.com/6dfzxz
I really want you to use
std::get
as the functor, because it's already provided as a library function!!Wouldn't it be great if we could write this line!?
... But it's a bit more terrible than that. You need to disambiguate which
get
to use:The problem is,
std::get
is overloaded to take 1.pair&
, 2.const pair&
, and 3.pair&&
as the parameters, so that it will work for any sort of pair as input. Unfortunately, the overloads get in the way of the template type deduction forstd::transform
, so our original lineyields
It doesn't know which overload of
std::get
you are asking for when deducing the template forstd::transform
, so you have to specify it manually. Casting the function pointer to the right type tells the compiler, "Hey, please use the overload whereget
takes aconst&
and returns aconst&
!"But at least we're using standard library components (yay)?
And in terms of number of lines, it's no worse than the other options:
http://ideone.com/6dfzxz
这个怎么样?
易于理解和调试。
How about this?
Simple to understand and debug.
使用 std::bind 怎么样?
(对于非 C++11 代码,将
std::bind
替换为boost::bind
)How about using
std::bind
?(Replace
std::bind
byboost::bind
for non-C++11 code)C++11 的另一种可能性是
std::mem_fn
,与
std::bind
的解决方案类似:another possibility from C++11 would be
std::mem_fn
, which is similar to solution withstd::bind
: