std :: map & lt; T, bool & gt ;, подсчитывают значения, которые являются истинными

У меня есть карта:

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;}
);

Есть ли более простой способ, чем определить лямбда-выражение для этого?

14

Решение

Я бы использовал 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"
12

Другие решения

Иногда простой цикл 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;
9

Вы могли бы использовать 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

Есть ли более простой способ, чем определить лямбда-выражение для этого?
нет.

Зависит от того, что вы имеете в виду под проще. Здесь важно помнить, что в C ++ value_type из std::map является pair<const key_type,mapped_type> и не только mapped_type. std::map::iterator перебирает это value_type и вам нужна оболочка для извлечения либо ключа, либо сопоставленного типа.

Все алгоритмы стандартной библиотеки C ++ работают на итераторах, а для std :: map это итератор для value_type. Таким образом, чтобы алгоритмы работали с отображаемым типом, нам нужно повторно отобразить value_type для сопоставленного типа и для этого либо

  1. Вам нужна вспомогательная именованная функция (до C ++ 11)
  2. Вам понадобится функтор
  3. Или вам понадобится лямбда.

Стоит отметить, что

«Алгоритмы стандартной библиотеки C ++ были бы гораздо приятнее использовать, если бы
В C ++ появилась поддержка лямбд

Предложение добавить лямбда-функции в стандарт C ++, N1958 = 06-002.

Так что, если вы думаете, что ваш код выглядит некрасиво, ваше намерение очистить код откажется от первоначальной мотивации лямбды.

Таким образом, если вы собираетесь использовать алгоритмы стандартной библиотеки C ++, вам нужно использовать лямбду, если это необходимо, как в случае с std :: map (period).
Конечно, вы все еще можете переписать, используя итеративная манера но это вопрос выбора и читаемости и «Читаемость лежит в глазах рецензентов»

0
По вопросам рекламы [email protected]