Std:: map <T, bool>, значения count, которые являются истинными
У меня есть карта:
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;}
);
Есть ли более простой способ, чем определить лямбда-выражение для этого?
Ответы
Ответ 1
Я бы использовал 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"
Ответ 2
Иногда простой цикл for немного ясен:
auto count = 0;
for (auto&& p : all_triggers_didfire)
if (p.second)
++count;
EDIT 1: я выложу исходный код, если кто-то не сможет увидеть историю изменений.
auto count = 0;
for (auto& p : all_triggers_didfire)
count += p.second;
Ответ 3
Вы можете использовать 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)
);
Ответ 4
Есть ли более простой способ, чем определить лямбда-выражение для этого? Нет.
Зависит от того, что вы имеете в виду, проще. Здесь важно помнить, что в С++ value_type
std::map
есть pair<const key_type,mapped_type>
, а не только тип mapped_type. std::map::iterator
выполняет итерацию по этому value_type
, и вам нужна оболочка для извлечения ключа или отображаемого типа.
Все алгоритмы стандартной библиотеки С++ работают на итераторах, а для std:: map - это итератор для value_type. Поэтому для того, чтобы алгоритмы работали над отображенным типом, нам нужно повторно отобразить тип value_type
для сопоставленного типа, и для этого либо
- Вам нужна вспомогательная именованная функция (pre С++ 11)
- Вам понадобится функтор
- Или вам понадобится лямбда.
Стоит отметить, что
"Алгоритмы стандартной библиотеки С++ были бы гораздо приятнее использовать, если У С++ была поддержка лямбда"
Предложение о добавлении лямбда-функций в стандарт С++, N1958 = 06-002.
Итак, если вы считаете, что ваш код выглядит уродливым, ваше намерение очистить код приведет к поражению оригинальной мотивации лямбда.
Таким образом, если вы намереваетесь использовать алгоритмы стандартной библиотеки С++, вам необходимо использовать lambda, если это необходимо, как в случае std:: map (period).
Конечно, вы все еще можете переписать с помощью итеративной манеры, но это вопрос выбора и удобочитаемости, а "читаемость лежит в глазах рецензентов"