Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing strings (for example in keys or values) without having the lib create a copy of it. #1916

Closed
aguaviva opened this issue Jan 29, 2020 · 11 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@aguaviva
Copy link

I am ok with just having a "const char *" of the string.

I have tried several times an I haven;t had any luck, all I get are copies.

@nlohmann
Copy link
Owner

Can you provide an example? I currently do not know what you mean exactly.

  • Please describe the steps to reproduce the issue. Can you provide a small but working code example?

  • What is the expected behavior?

  • And what is the actual behavior instead?

@nlohmann nlohmann added the state: needs more info the author of the issue needs to provide more details label Jan 31, 2020
@alfaunits
Copy link

I feel ya, aguaviva.
I had the use of the same a few times.

If we ask for, say, json_var["name"] we would get a new JSON object, converted to a string.
Being able to instead get a string object, pointing to actual memory inside the json_var, where the vale of the element "name" would reduce memiry need.
Talking about very large JSONs of course.

@nickaein
Copy link
Contributor

nickaein commented Feb 2, 2020

How about using get_ptr() to get a pointer to the stored object?

@alfaunits
Copy link

Would that not create a copy of an std::string when we try to use it as a string?

@nickaein
Copy link
Contributor

nickaein commented Feb 2, 2020

Correct. The following code is one way to test it (live example):

Note: Per documentation, writing data to the returned pointer is discouraged. Take following code just as a demonstration.

#include "json.hpp"
#include <iostream>

int main() {

  nlohmann::json j;
  j["key"] = "hello";

  auto p1 = j["key"].get_ptr<std::string *>();
  auto p2 = j["key"].get_ptr<std::string *>();

  std::cout << "Addresses: " << p1 << "," << p2 << std::endl;

  std::cout << "Original:  " << j["key"].get<std::string>() << "," << *p1 << ","
            << *p2 << std::endl;

  *p1 += "1";
  std::cout << "Change p1: " << j["key"].get<std::string>() << "," << *p1 << ","
            << *p2 << std::endl;

  *p2 += "2";
  std::cout << "Change p2: " << j["key"].get<std::string>() << "," << *p1 << ","
            << *p2 << std::endl;

  return 0;
}

Typical output:

Addresses: 0xe37b20,0xe37b20
Original:  hello,hello,hello
Change p1: hello1,hello1,hello1
Change p2: hello12,hello12,hello12

@alfaunits
Copy link

alfaunits commented Feb 2, 2020 via email

@aguaviva
Copy link
Author

aguaviva commented Feb 2, 2020

@nlohmann any chance that we could have const string &myvar = json["myvar"] 'to not return a copy as the default behaviour? This would speed up things a lot :)

@nlohmann
Copy link
Owner

nlohmann commented Feb 8, 2020

json::operator[] returns a (const) reference of type json&. From there, you can use get, get_ref or get_ptr to access the value for various conversions.

@nlohmann nlohmann added solution: proposed fix a fix for the issue has been proposed and waits for confirmation and removed state: needs more info the author of the issue needs to provide more details labels Feb 8, 2020
@aguaviva
Copy link
Author

aguaviva commented Feb 8, 2020

why not make an operator overload to get json::operator[] return a std::string?

@nlohmann
Copy link
Owner

nlohmann commented Feb 9, 2020

For several reasons:

  • The type of the string is templated. It is std::string by default, but it could be another type. That's why the get_ptr and get_ref functions are do delicate as they allow you to dig into the JSON type which may lead to problems.
  • What happens if you write std::string& mystring = myjson["foo"], but myjson["foo"] is an integer?

@aguaviva
Copy link
Author

aguaviva commented Feb 10, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

4 participants