我想将与谓词(等于整数)匹配的值从a复制map<string,int>到a vector<int>.
这是我试过的:
#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 ) );
}
);
}
Run Code Online (Sandbox Code Playgroud)
来自g ++ 4.6.1的错误消息是:
error: cannot convert 'std::pair<const std::basic_string<char>, int>' to 'int' in assignment
Run Code Online (Sandbox Code Playgroud)
有没有办法调整示例来执行上述复制?
Kle*_*ist 12
因为你从复制副本失败的map::iterator它迭代pair<string const,int>到vector::iterator它迭代int.
替换copy_if为矢量for_each并对其执行操作push_back.
std::for_each( m.begin(), m.end(),
[&v] ( std::pair< std::string const,int > const&it ) {
if ( 0 == ( it.second % 2 ) ) {
v.push_back(it.second);
}
}
);
Run Code Online (Sandbox Code Playgroud)
Man*_*rse 12
有了boost::range它就像:
boost::push_back(
v,
m | boost::adaptors::map_values
| boost::adaptors::filtered([](int val){ return 0 == (val % 2); }));
Run Code Online (Sandbox Code Playgroud)
编译器错误实际上非常简洁:
error: cannot convert 'std::pair<const std::basic_string<char>, int>' to 'int' in assignment
Run Code Online (Sandbox Code Playgroud)
而这正是问题所在.在map你从复制具有迭代器解引用的pair<KEY,VALUE>,而且也没有办法隐含变换一个pair<KEY,VALUE>只是一个VALUE.
因此,你不能使用copy或copy_if从a复制map到a vector; 但标准库确实提供了一种可以创造性地使用的算法transform. transform非常相似copy,因为它需要两个源迭代器和一个目标迭代器.差异transform还在于实现实际转换的一元函数.使用C++ 11 lambda,您可以将a的全部内容复制map到vector如下:
transform( m.begin(), m.end(), back_inserter(v), [] (const MyMap::value_type& vt)
{
return vt.second;
});
Run Code Online (Sandbox Code Playgroud)
如果您不想复制整个内容map,但只有一些符合certian标准的元素,该怎么办?简单,只需使用transform_if.
那是什么,你说?transform_if标准库中没有?好吧,你确实有一点意见.令人沮丧的是transform_if,标准库中没有.但写一个是一个足够简单的任务.这是代码:
template<class InputIterator, class OutputIterator, class UnaryFunction, class Predicate>
OutputIterator transform_if(InputIterator first,
InputIterator last,
OutputIterator result,
UnaryFunction f,
Predicate pred)
{
for (; first != last; ++first)
{
if( pred(*first) )
*result++ = f(*first);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
正如您所料,使用transform_if就像把copy_if它和它一起捣碎一样transform.这里有一些psudo代码来演示:
transform_if( m.begin(), m.end(), back_inserter(v),
[] (const MyMap::value_type& vt) // The UnaryFunction takes a pair<K,V> and returns a V
{
return vt.second;
}, [] (const MyMap::value_type& vt) // The predicate returns true if this item should be copied
{
return 0 == (vt.second%2);
} );
Run Code Online (Sandbox Code Playgroud)