У меня есть карта:
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;}
);
Есть ли более простой способ, чем определить лямбда-выражение для этого?
Я бы использовал 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"
Иногда простой цикл 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;
Вы могли бы использовать 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)
);
Есть ли более простой способ, чем определить лямбда-выражение для этого?
нет.
Зависит от того, что вы имеете в виду под проще. Здесь важно помнить, что в 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
для сопоставленного типа и для этого либо
Стоит отметить, что
«Алгоритмы стандартной библиотеки C ++ были бы гораздо приятнее использовать, если бы
В C ++ появилась поддержка лямбд
Предложение добавить лямбда-функции в стандарт C ++, N1958 = 06-002.
Так что, если вы думаете, что ваш код выглядит некрасиво, ваше намерение очистить код откажется от первоначальной мотивации лямбды.
Таким образом, если вы собираетесь использовать алгоритмы стандартной библиотеки C ++, вам нужно использовать лямбду, если это необходимо, как в случае с std :: map (period).
Конечно, вы все еще можете переписать, используя итеративная манера но это вопрос выбора и читаемости и «Читаемость лежит в глазах рецензентов»