yaml-cpp Самый простой способ перебрать карту с неопределенными значениями
Я хотел бы получить каждый узел на карте, не зная ключей.
Мой YAML выглядит так:
characterType :
type1 :
attribute1 : something
attribute2 : something
type2 :
attribute1 : something
attribute2 : something
Я не знаю, сколько "типов" будет объявлено или как будут называться эти ключи. Вот почему я пытаюсь перебрать карту.
struct CharacterType{
std::string attribute1;
std::string attribute2;
};
namespace YAML{
template<>
struct convert<CharacterType>{
static bool decode(const Node& node, CharacterType& cType){
cType.attribute1 = node["attribute1"].as<std::string>();
cType.attribute2 = node["attribute2"].as<std::string>();
return true;
}
};
}
---------------------
std::vector<CharacterType> cTypeList;
for(YAML::const_iterator it=node["characterType"].begin(); it != node["characterType"].end(); ++it){
cTypeList.push_back(it->as<CharacterType>());
}
Предыдущий код не доставляет проблем при компиляции, но затем во время выполнения я получаю эту ошибку: terminate вызывается после создания экземпляра YAML::TypedBadConversion<CharacterType>
Я также пытался использовать субиндекс вместо итератора, получая ту же ошибку.
Я уверен, что делаю что-то не так, я просто не вижу этого.
2 ответа
Когда вы выполняете итерацию по карте, итератор указывает на пару ключ / значение, а не на один узел. Например:
YAML::Node characterType = node["characterType"];
for(YAML::const_iterator it=characterType.begin();it != characterType.end();++it) {
std::string key = it->first.as<std::string>(); // <- key
cTypeList.push_back(it->second.as<CharacterType>()); // <- value
}
(Причина, по которой ваш код скомпилирован, даже если ваш узел является узлом карты, заключается в том, что YAML::Node
эффективно динамически типизирован, поэтому его итератор должен действовать (статически) как итератор последовательности и итератор карты.)
Ответ от @jesse-beder правильный, я предлагаю еще один вариант с использованием цикла for на основе диапазона, как показано ниже:
for(const auto& characterType : node["characterType"]) {
std::string key = characterType.first.as<std::string>();
cTypeList.push_back(characterType.second.as<CharacterType>());
}