我想了解如何在C ++中使用 Lambda函数。
我正在使用自定义类型,如下所示:
struct my_toy_t {
uint32_t id;
cv::Rect box;
cv::Mat data;
}
typedef std::map<uint32_t, my_toy_t*> my_toy_map_t;
和
int main() {
my_toy_map_t input_map;
my_toy_map_t output_map;
// Some insertions in input_map...
my_toy_map_t::iterator it;
for (it = input_map.begin(); it != input_map.end(); ++it)
{
if (check_cond(it->second->box)) {
output_map.insert(std::make_pair(it->first, it->second));
input_map.erase(it->first);
}
}
return 0;
}
bool check_cond(cv::Rect box) {
if (box.area > 100)
return true;
else
return false;
}
可能会注意到my_toy_map_t
只是std::map<uint32_t, my_toy_t*>
,而check_cond
函数会检查一个简单的条件。
是否可以使用Lamba函数翻译此代码(output map
中的插入以及input_map
如果check_cond
返回true
的重新调用) ?
答案 0 :(得分:2)
可能是std::copy_if
和std::inserter
?
std::copy_if(input_map.begin(),input_map.end(),
std::inserter(output_map,output_map.end()) ,
[](const std::pair<uint32_t, my_toy_t*>& x ){
return (x.second)->box.area > 100;
}
);
为了删除我可以想到这个:
my_toy_map_t temp;
std::remove_copy_if(input_map.begin(), input_map.end(),
inserter(temp, temp.end()),
[](const std::pair<uint32_t, my_toy_t*>& x ){
return (x.second)->box.area > 100;
} );
input_map.swap(temp);
答案 1 :(得分:2)
首先,不需要指针。如果要避免副本,请使用std::reference_wrapper
。
其次,您正在迭代容器,并在流程中修改容器。这有未定义的行为:插入/删除操作后,以前的迭代器无效。
您要做的是真正的 过滤过程 :获取传递给定条件的容器元素,并使用它填充另一个容器。<登记/>
使用标准库提供的某些通用算法可以轻松完成。例如,最简单的方法是使用std::copy_if
:
int main()
{
std::copy_if( std::begin( input ) , std::end( input ) , std::inserter( output , std::end( output ) ) , [](const std::pair<uint32_t,my_toy_t>& pair ) { return pair->second.box.area > 100; });
}
如您所见,函数std::copy_if()
期望可调用实体作为过滤的谓词。在这种情况下,最简单的方法,并且因为您询问如何使用lambda改进过滤,是传递lambda函数。
答案 2 :(得分:1)
可以将std::for_each与mutable
lambda
std::for_each(input_map.begin(), input_map.end(),
[&output_map](const std::pair<uint32_t,my_toy_t*> &it) mutable{
// ^^ ^^^^^^^
if (it.second->box.area > 100)
{
output_map.insert(it);
}
});
建议:您最好使用smart pointers + STL container
而不是原始指针raw pointer + STL container
。