我有一张地图:
std::map<std::string, bool> all_triggers_didfire;
我填写它,最后想获得真实值的数量。以下代码有效:
int count_did_fire = std::count_if(
all_triggers_didfire.begin(),
all_triggers_didfire.end(),
[](std::pair<std::string, bool> p){return p.second;}
);
有没有比为此定义lambda表达式更简单的方法?
答案 0 :(得分:12)
我会使用std :: set而不是std :: map。它们在语义上是等价的,但使用std :: set更容易。例如:
std::set<std::string> triggers_that_did_fire;
int count_did_fire = triggers_that_did_fire.size();
当您最初填充triggers_that_did_fire
集时,您可以执行以下操作:
triggers_that_did_fire.insert(mystring); //equivalent to setting to "true" in your map
triggers_that_did_fire.remove(mystring); //equivalent to setting to "false"
答案 1 :(得分:9)
有时,一个简单的for循环更清晰:
auto count = 0;
for (auto&& p : all_triggers_didfire)
if (p.second)
++count;
编辑1:我发布原始代码,万一有人看不到编辑记录..
auto count = 0;
for (auto& p : all_triggers_didfire)
count += p.second;
答案 2 :(得分:4)
您可以使用std::mem_fn
将对数据成员的访问权限包装到可调用对象中:
int count_did_fire = std::count_if(
all_triggers_didfire.begin(),
all_triggers_didfire.end(),
std::mem_fn(&decltype(all_triggers_didfire)::value_type::second)
);
答案 3 :(得分:0)
有没有比为此定义lambda表达式更简单的方法? 否强>
更容易取决于您的意思。这里要记住的一件重要事情是,在C ++中,value_type
的{{1}}是std::map
,而不仅仅是mapped_type。 pair<const key_type,mapped_type>
遍历此std::map::iterator
,您需要一个包装器来获取密钥或映射类型。
所有C ++标准库算法都适用于迭代器,而std :: map则是迭代器的value_type。因此,要使算法处理映射类型,我们需要将value_type
重新映射到映射类型,并为此
值得注意的是
&#34;如果使用C ++标准库算法会更加愉快 C ++支持lambdas&#34;
将lambda函数添加到C ++标准的建议,N1958 = 06-002。
因此,如果您认为您的代码看起来很丑陋,那么您清理代码的意图将会破坏lambda的原始动机。
因此,如果您打算使用C ++标准库算法,则需要使用lambda(如果需要,如std :: map(句点))。 当然,您仍然可以使用iterative manner重新编写,但这是一个选择和可读性的问题, &#34;可读性在于审稿人的眼中&#34;