简体   繁体   中英

yaml-cpp to std::vector iteration weird behaviour

I found something (in my opinion) rather weird while reading in a yaml file. Maybe one of you can explain me the difference between the two codes.

The yaml file I'm trying to read looks something like this:

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.

Now I'm trying to read this into a std::map<std::vector<int>, std::map<int, double> > for later use.

I tried to do it using the STL conversion from yaml-cpp:

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

But since this did not work (don't have the error message right now, but this isn't really what the question is about just as an explanation) I wrote my own read routine like this:

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
}

And it results in some weird output:

937068720 21864 0 0 
937068720 21864 0 1 

However if I change it to this code:

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
}

Everything is as expected:

0 0 0 0
0 0 0 1

What is the difference between the two? why do I have to specifically declare the vector? Even putting brackets around the statement before .begin() does not make a difference. Like this:

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

Can somebody explain this to me? What is the difference between the first and the second code?

And since I'm new to YAML I'm happy about any improvement suggestions to reading such a file, this is however not my primary concern.

Your YAML isn't valid, See. eg,, an online parser ; and yaml-cpp agrees: running the utility function util/parse with your YAML gives:

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

Perhaps you meant something like:

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

This, at least, is valid YAML, but it's probably not of the format you're expecting. Here's an analysis:

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

In standard library functions, this would be a

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM