4

I'm reading the tutorial code here: https://code.google.com/p/yaml-cpp/wiki/Tutorial

One example goes like this:

YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]");

for (YAML::const_iterator it=primes.begin();it!=primes.end();++it) {
  std::cout << it->as<int>() << "\n";
}

And the next like this:

YAML::Node lineup = YAML::Load("{1B: Prince Fielder, 2B: Rickie Weeks, LF: Ryan Braun}");

for(YAML::const_iterator it=lineup.begin();it!=lineup.end();++it) {
  std::cout << "Playing at " << it->first.as<std::string>() << " is " << it->second.as<std::string>() << "\n";
}

However, if you swap the YAML files between these two cases, you will get an error, as you are accessing a map iterator for a sequence or vice versa:

terminate called after throwing an instance of 'YAML::InvalidNode'
what():  yaml-cpp: error at line 0, column 0: invalid node; this may result from using a map iterator as a sequence iterator, or vice-versa

For an arbitrary YAML input, how can I determine whether I am dealing with a sequence or a map in the loop (ie whether I should be using ->first or not) without using a try/catch block?

I tried looking for the documentation, but I could not find it.

UPDATE:

This is what I am trying to do:

YAML::Node config = YAML::LoadFile(filename);

for (YAML::const_iterator it=config.begin();it!=config.end();++it) {
    if (it->Type() == YAML::NodeType::Map) { // exception
        std::cout << it->first.as<std::string>();
    } else if (it->Type() == YAML::NodeType::Sequence) {
        std::cout << it->as<std::string>();
    }
}

But when I run the code I get the exception as above. It compiles fine.

I am using the yaml-cpp which comes with ubuntu 14.04 (0.5.1).

jeremy
  • 4,421
  • 4
  • 23
  • 27

1 Answers1

3

You can either

switch (node.Type()) {
  case Null: // ...
  case Scalar: // ...
  case Sequence: // ...
  case Map: // ...
  case Undefined: // ...
}

or query explicitly, e.g.:

if (node.IsSequence()) {
  // ...
}

(I added this bit to the Tutorial.)

Edit: In your specific example, you should check config.Type() before you iterate, not the type of any of the nodes during your iteration.

Jesse Beder
  • 33,081
  • 21
  • 109
  • 146
  • Thanks for your answer Jesse, but I'm not quite sure how this fixes the problem I am having. My problem is that I can't work out how to get the node object that I can call these functions on. I have added the code I am trying to write to my question. – jeremy Oct 03 '14 at 15:11
  • @jeremy, I updated my answer for your specific example. – Jesse Beder Oct 03 '14 at 15:22