Я хочу сделать это :

std::map<std::string, bool> mapTrafficLights;

mapTrafficLights.emplace("RED", true);
mapTrafficLights.emplace("GREEN", true);
mapTrafficLights.emplace("ORANGE", true);

std::for_each(mapTrafficLights.begin(), mapTrafficLights.end(), []
(std::pair<std::string, bool>& it) {it.second = false; });

std::for_each(mapTrafficLights.begin(), mapTrafficLights.end(), [](std::pair<std::string, bool> it) {std::cout << it.first << " " << ((it.second) ? "ON" : "OFF") << std::endl; });

Строка перед последней не будет компилироваться, если я сохраню ссылочный символ «&», но когда я удалю ее, она компилируется, но не обновляет значения моей карты. Я хочу установить для всех логических значений значение false, но с этим стилем кода в одной строке с использованием инструментов STL.

0
Aminos 27 Дек 2015 в 17:01

2 ответа

Лучший ответ

Тип элементов карты - std::pair<const std::string, bool>. Это означает, что ваша лямбда-подпись потребует преобразования типа в std::pair<std::string, bool>, что потребует создания временного объекта. И вы не можете привязать неконстантную ссылку lvalue к временному. Тебе нужно

std::for_each(mapTrafficLights.begin(), mapTrafficLights.end(),
             [] (std::pair<const std::string, bool>& it) {it.second = false; });
                           ^^^^^

Или используйте карту value_type.

typedef std::map<std::string, bool> str_bool_map;
std::for_each(mapTrafficLights.begin(), mapTrafficLights.end(),
             [] (str_bool_map::value_type& it) {it.second = false; });

Обратите внимание, что для изменения диапазонов более идиоматично использовать std::transform. Однако цикл на основе диапазона может быть самым простым решением:

for (auto& p : mapTrafficLights) p.second = false;
6
juanchopanza 27 Дек 2015 в 14:25

value_type из std::map<std::string, bool> равно std::pair<const std::string, bool>>. В вашем коде отсутствует const.

Поскольку вы явно используете C ++ 11, почему бы не использовать цикл range-for и автоматическое определение типа?

for(auto& e: mapTrafficLights) {
    e.second = false;
}
4
Revolver_Ocelot 27 Дек 2015 в 14:12