如何将_if从地图复制到矢量?
我想将与谓词(等于整数)匹配的值从 map
复制到 vector
。
这是我尝试过的:
#include <map>
#include <vector>
#include <algorithm>
int main()
{
std::vector< int > v;
std::map< std::string, int > m;
m[ "1" ] = 1;
m[ "2" ] = 2;
m[ "3" ] = 3;
m[ "4" ] = 4;
m[ "5" ] = 5;
std::copy_if( m.begin(), m.end(), v.begin(),
[] ( const std::pair< std::string,int > &it )
{
return ( 0 == ( it.second % 2 ) );
}
);
}
g++ 4.6.1 的错误消息是:
error: cannot convert 'std::pair<const std::basic_string<char>, int>' to 'int' in assignment
有没有办法调整示例来执行上述复制?
I'd like to copy values that match a predicate (equal ints) from a map<string,int>
to a vector<int>
.
This is what I tried:
#include <map>
#include <vector>
#include <algorithm>
int main()
{
std::vector< int > v;
std::map< std::string, int > m;
m[ "1" ] = 1;
m[ "2" ] = 2;
m[ "3" ] = 3;
m[ "4" ] = 4;
m[ "5" ] = 5;
std::copy_if( m.begin(), m.end(), v.begin(),
[] ( const std::pair< std::string,int > &it )
{
return ( 0 == ( it.second % 2 ) );
}
);
}
The error message from g++ 4.6.1 is :
error: cannot convert 'std::pair<const std::basic_string<char>, int>' to 'int' in assignment
Is there a way to adjust the example to do the above copy?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用
boost::range
就很简单:With
boost::range
it is as easy as:问题
复制失败,因为您正在从迭代
pair
的map::iterator
复制到vector::iterator
code> 迭代int
。解决方案
将
copy_if
替换为for_each
并对向量执行push_back
。例子
Problem
The copy fails because you're copying from a
map::iterator
which iterates overpair<string const,int>
to avector::iterator
which iterates overint
.Solution
Replace
copy_if
withfor_each
and do apush_back
on your vector.Example
编译器错误实际上非常简洁:
这正是问题所在。您要复制的与
map
具有取消引用pair
的迭代器,并且无法隐式转换 < code>pairVALUE
。因此,您无法使用
copy
或copy_if
从map
复制到vector
;但标准库确实提供了一种可以使用的算法,创造性地称为“变换”。transform
与copy
非常相似,因为它需要两个源迭代器和一个目标迭代器。不同之处在于transform
还采用一个一元函数来执行实际的转换。使用 C++11 lambda,您可以将map
的全部内容复制到vector
,如下所示:如果您不想复制
map
,但只有一些元素满足某些标准?很简单,只需使用transform_if
即可。你说那是什么?标准库中没有
transform_if
?嗯,是的,你说的确实有道理。令人沮丧的是,标准库中没有transform_if
。然而,编写一个是一项足够简单的任务。代码如下:正如您所料,使用
transform_if
就像采用copy_if
并将其与transform
混合在一起。下面是一些伪代码来演示:The compiler error is actually quite succinct:
And that's exactly what the problem is. The
map
you're copying from has iterators that dereference to apair<KEY,VALUE>
, and there's no way to implicitly transform apair<KEY,VALUE>
to just aVALUE
.Because of this, you can't use
copy
orcopy_if
to copy from amap
to avector
; but the Standard Library does provide an algorithm you can use, creatively calledtransform
.transform
is very similar tocopy
in that it takes two source iterators and a destination iterator. The difference istransform
also takes a unary function that does the actual transformation. Using a C++11 lambda, you can copy the entire contents of amap
to avector
like this:What if you don't want to copy the entire contents of the
map
, but only some elements meeting certian criteria? Simple, just usetransform_if
.What's that, you say? There is no
transform_if
in the Standard Library? Well yeah, you do have a point there. Frustratingly, there is notransform_if
in the Standard Library. However writing one is a simple enough task. Here's the code:As you might expect, using
transform_if
is like takingcopy_if
and mashing it together withtransform
. Here's some psudo-code to demonstrate:std::copy_if
不允许您从一种类型转移到另一种类型,只能过滤要复制的内容。您可以使用 std::transform 删除密钥,然后使用 std::remove_if :
但是,普通的 for 循环会更高效并且更容易读。
std::copy_if
won't allow you to transfer from one type to another, only to filter what to copy.You could use
std::transform
to get rid of the key and then usestd::remove_if
:However, a plain for loop would be more efficient and a lot easier to read.
我无法理解为什么简单的 for 循环解决方案不是首选方法,对于这个问题,
除了它使代码更具可读性之外,它的性能也更好。我编写了一个简单的基准测试来查看 for 循环与其他建议的解决方案相比如何执行:
我得到的结果如下:
I cannot understand why the simple for loop solution is not the preferred approach, for this problem
Except that it makes the code more readable it performs better. I wrote a simple benchmark to see how a for loop performs compared to the other proposed solutions:
The results I got are the following:
大概您只想从
map
中检索关联的值,而不是键。STL 的 SGI 版本具有用于此类任务的
select1st
和select2nd
迭代器。然而,就我个人而言,我认为这实际上不应该通过复制来完成——您正在转换数据,而不是复制它。因此,我建议使用 std::transform 和函子来返回对中的第二项。
Presumably you just want to retrieve the associated values from the
map
, not the keys.The SGI version of STL has
select1st
andselect2nd
iterators for this kind of task.Personally, however, I don't think this should really be done with copy -- you're transforming the data, not copying it. As such, I'd advise using
std::transform
with a functor to return the second item in the pair.