yaml-cpp to std :: странное поведение векторной итерации - PullRequest
1 голос
/ 31 октября 2019

Я нашел что-то (на мой взгляд) довольно странное при чтении в файле yaml. Может быть, один из вас может объяснить мне разницу между двумя кодами.

Файл yaml, который я пытаюсь прочитать, выглядит примерно так:

map:
  - [0 0 0 0]
    - 0:
      - 0.123
    - 1:
      - -0.234
  - [0 0 0 1]
    - 0:
      - 0.00
    - 1:
      - 1.234
# and many more vector to int to doubles.

Теперь я пытаюсь прочитатьэто в std::map<std::vector<int>, std::map<int, double> > для дальнейшего использования.

Я попытался сделать это, используя преобразование STL из yaml-cpp:

std::map<std::vector<int>, std::map<int, double> > the_map = node.as<std::map<std::vector<int>, std::map<int, double> > >();

Но так как это не сработало (не имеютсообщение об ошибке прямо сейчас, но это не совсем то, о чем вопрос, просто как объяснение) Я написал свою собственную процедуру чтения так:

YAML::Node node = YAML::LoadFile(name);
for(YAML::const_iterator n = node["map"].begin(); n != node["map"].end(); ++n){
    auto n_0 = (*n).begin();
    for(auto it = n_0->first.as<std::vector<int> >().begin(); it != n_0->first.as<std::vector<int> >().end(); ++it){
        std::cout << *it << " ";
    }
    // Some more stuff
}

И это приводит к некоторому странному выводу:

937068720 21864 0 0 
937068720 21864 0 1 

Однако, если я изменю его на этот код:

YAML::Node node = YAML::LoadFile(name);
for(YAML::const_iterator n = node["map"].begin(); n != node["map"].end(); ++n){
    auto n_0 = (*n).begin();
    std::vector<int> vec = n_0->first.as<std::vector<int> >();
    for(auto it = vec.begin(); it != vec.end(); ++it){
        std::cout << *it << " ";
    }
    // Some more stuff
}

Все как положено:

0 0 0 0
0 0 0 1

В чем разница между этими двумя? почему я должен специально объявить вектор? Даже заключение в скобки вокруг оператора до .begin() не имеет значения. Вот так:

for(auto it = (n_0->first.as<std::vector<int> >()).begin(); it != (n_0->first.as<std::vector<int> >()).end(); ++it)

Может кто-нибудь объяснить это мне? В чем разница между первым и вторым кодом?

И так как я новичок в YAML, я рад любым предложениям по улучшению чтения такого файла, однако это не моя главная забота.

1 Ответ

0 голосов
/ 31 октября 2019

Ваш YAML недействителен! Смотрите, например, онлайн-анализатор yaml-cpp согласен: запуск утилиты util/parse с вашим YAML дает:

yaml-cpp: error at line 3, column 5: end of sequence not found

Возможно, вы имели в виду что-то вроде:

map:
  [0 0 0 0]:
    - 0:
      - 0.123
    - 1:
      - -0.234
  [0 0 0 1]:
    - 0:
      - 0.00
    - 1:
      - 1.234

Это, по крайней мере, допустимый YAML, но это, вероятно, не тот формат, который вы ожидаете. Вот анализ:

map:           // map of string ->
  [0 0 0 0]:   //  map of vector of int ->
    - 0:       //   vector of map of int to ->
      - 0.123  //    vector of double
    - 1:
      - -0.234
  [0 0 0 1]:
    - 0:
      - 0.00
    - 1:
      - 1.234

В стандартных функциях библиотеки это будет

std::map<string, std::map<std::vector<int>, std::vector<std::map<int, std::vector<double>>>>>
...