0

I need to write a function that will take two arguments, a key path and a value, and will populate a JSON object. However, it does not work because the values I'm using are passed by value; I do not know how to refactor the function so pointers are used instead.

This is what I have, it does not produce any error, but it does not update the root, what do I need to change so that value is persistent?

void JSONConfig::setValue(string key, Json::Value value)
{
  stringstream tokenizer(key);
  string token;
  string lastToken;
  Json::Value node = root;

  while (getline(tokenizer, token, '.'))
  {
    if (!lastToken.empty()) node = node[lastToken];
    lastToken = token;
  }
  
  if (!lastToken.empty()) 
  {
    node[lastToken] = value;
  }
}
Yanick Rochon
  • 51,409
  • 25
  • 133
  • 214
  • Could you make your code reproducible? Where does `root` come from, I guess it should be `node` instead of `note` and why should `root` be updated in the example above? You are not changing it anywhere... – 2b-t May 18 '21 at 19:47
  • I fixed the typo. I have the code on another, older, machine which is not on the Internet. – Yanick Rochon May 18 '21 at 19:52
  • This is a design issue. It doesn't do any good to set something if you don't have anywhere to set it. (You're actually setting the value on node, but that's a local temporary.) – Kenny Ostrom May 18 '21 at 19:55
  • No problem. But what should cause `root` to update in the first place? Is `root` a `Json::Value` as well? `Json::Value node = root` creates a copy of `root`, you then continue to modify it and then it goes out of scope and you lose the changes. Why do not use `root` instead of `node` in the first place? – 2b-t May 18 '21 at 19:56
  • Is this a member function of a class with root? And if you have root, why don't you just set it there? Did you mean to make node a reference to root? – Kenny Ostrom May 18 '21 at 19:58

1 Answers1

0

In the end, this is what I wrote, and it seems to work.

void JSONConfig::setValue(string key, Json::Value value)
{
  stringstream tokenizer(key);
  string token;
  string lastToken;
  Json::Value *node = &root;

  while (getline(tokenizer, token, '.'))
  {
    if (!lastToken.empty()) node = & ((*node)[lastToken]);
    lastToken = token;
  }
  
  if (!lastToken.empty()) 
  {
    (*node)[lastToken] = value;
  }
}
Yanick Rochon
  • 51,409
  • 25
  • 133
  • 214