4

Starting with a string representing a path to a node that I want to retrieve data from, such as "a.b.c". Currently, the code that I am using to transverse the node hierarchy to reach that node looks something like this (may not compile, but you get the idea):

string keyPath("a.b.c");
vector<string> keyPieces(split(keyPath, "."));

const YAML::Node *currNode = &rootNode;
for_each(begin(keyPieces), end(keyPieces), [&](const string &key)
{
    // for simplicity, ignore indexing on a possible scalar node
    // and using a string index on a sequence node
    if ((*currNode)[key])
    {
        currNode = &((*currNode)[key]);
    }
});

// assuming a valid path, currNode should be pointing at the node
// described in the path (i.e. currNode is pointing at the "c" node)

The above code seems to work correctly, but I am wondering if there is a better way to do the node transversal assignment. Using direct node assignment (currNode = currNode[key]), instead of a pointer/address of (currNode = &((*currNode)[key])), seems to end up creating references between nodes instead of transversing from one node to the next.

Is there a 'cleaner' or more idiomatic way to accomplish this?

Canute Bigler
  • 220
  • 1
  • 9

2 Answers2

1

There's no way to do that now (this is a use case I hadn't thought of), but it's a good idea. I've filed a bug (http://code.google.com/p/yaml-cpp/issues/detail?id=189).

Jesse Beder
  • 33,081
  • 21
  • 109
  • 146
1

I was doing a similar thing, and found out that this capability was added sometime ago, called Node::reset()

So,

string keyPath("a.b.c");
vector<string> keyPieces(split(keyPath, "."));

YAML::Node currNode = rootNode;
for_each(begin(keyPieces), end(keyPieces), [&](const string &key)
{
    if (currNode[key])
    {
        currNode.reset(currNode[key]);
    }
});

should work as intended.

Kristóf Szalay
  • 1,177
  • 1
  • 8
  • 19
  • Indeed, that was the result of Jesse Beder's answer. It's unfortunate Google Code ending meant that links would break, but here's an [Internet Archive link](https://web.archive.org/web/20160420182224/https://code.google.com/p/yaml-cpp/issues/detail?id=189). –  Feb 12 '17 at 03:29
  • currNode is const, but you're calling reset(), which is non-const (discards qualifiers), and shouldn't compile. I'm also not seeing a difference between "currNode.reset(currNode[key])" and "currNode = currNode[key]" even if it did compile. – Matthew Kraus Jun 01 '18 at 21:52
  • yup, removed the const. for the second statement: but this is the very problem why reset was needed: currnode=currnode[key] will *modify the root node as well* – Kristóf Szalay Jun 29 '18 at 17:06