-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
How to construct an iteratable usage in nlohmann json? #636
Comments
If you're storing pointers in the |
This seems like a really bad thing to do. Why would you not use |
The reason is that I kind of want enjoy the easy management and pass of a flexible json object, with that object I could easily bind the tag and other related thing together, but with vector, I have to use different type and glue, which is not look good as json. |
There is no way to store pointers as JSON values, unless you want to covert them to 64 bit unsigned integers. |
OK, I will try to have some pointer store mechanism and try. I think nlohmann json is so close to enable c++ to deliver something like python. The only barrier now is the pointer store mechanism. If nlohmann json could enable some thing like
There is no need to use anything like iterator . |
That example would not work, because the range for (you must wrap |
Yes, I know it not work. I just want to know if it is possible to do this in nlohmann json, I would very glad to see this as a useful extension, this could potentially change the way how we write cpp code. |
I understand, but I fear that this is out of scope of this library. It would require a lot of extensions that are unrelated to JSON. And I am not sure whether the example you provided is actually possible in C++ without pointers and reinterpret_casts. |
That is just my suggestion, I would try some thing weak version to enable the usage here
The drawback is that user still need to know type of the pointer. |
Then again: storing pointers has nothing to do with JSON. |
I know I need to convert it to something like uint64_t |
You may use something like this: #include "json.hpp"
using json = nlohmann::json;
class Foo
{
public:
void bar() { std::cout << "bar()" << std::endl; }
};
void to_json(json& j, const Foo& f) {
j = reinterpret_cast<uint64_t>(std::addressof(f));
}
void from_json(const json& j, Foo& f) {
f = *reinterpret_cast<Foo*>(j.get<uint64_t>());
}
int main()
{
Foo f;
f.bar();
json j = f;
Foo f2 = j;
f2.bar();
} |
I close this issue as there is nothing to be done for the library. |
Thank you for the example code, it is very useful. |
I am trying to modify a little bit of the code and use pointer type to avoid the copy constructor of Foo. I tried the code like this: #include "json.hpp"
using json = nlohmann::json;
class Foo
{
public:
void bar() { std::cout << "bar()" << std::endl; }
};
void to_json(json& j, const Foo* f) {
j = reinterpret_cast<uint64_t>(f);
}
void from_json(const json& j, Foo*& f) {
f = reinterpret_cast<Foo*>(j.get<uint64_t>());
}
int main()
{
Foo f;
f.bar();
json j=&f;
Foo *f2;
f2=j;
}
But I meet below error:
Is it possible for the Foo* as left value of assignment? |
I'm not sure. Maybe @theodelrieu has an idea. He wrote the whole custom-type conversion. |
Hi, I think you can achieve this, by specializing (I did not compile any of this though) namespace nlohmann {
// You can also fully specialize on Foo*
template <typename T>
struct adl_serializer<T*> {
static void to_json(json& j, const T* f) { /* ... */ }
static void from_json(const json& j, T*& f) { /* ... */ }
};
} Let me know if that works! |
Hi I tried the code you provide , still report the same error, I can assign to json, but not assign from json
The full code is here, my environment is Ubuntu 16.04 + gcc 5.4.0 #include "json.hpp"
using json = nlohmann::json;
class Foo
{
public:
void bar() {
std::cout << "bar()" << std::endl;
}
};
namespace nlohmann {
// You can also fully specialize on Foo*
template <typename T>
struct adl_serializer<T*> {
static void to_json(json& j, const T* f) {
j=reinterpret_cast<uintptr_t>(f);
}
static void from_json(const json& j, T*& f) {
f=reinterpret_cast<T*>(j.get<uintptr_t>());
}
};
}
int main()
{
Foo f;
f.bar();
json j=&f;
Foo *f2=j;
}
|
Oh, I think I understand, there is a method This could be changed, it would break existing code though, I don't know what @nlohmann thinks about this. Personally, I think we should change the current behaviour, it made sense before that conversion mechanism was introduced. |
I see. So the serializer feature for now is not able to deal with pointer type due to this design. I am not familiar with the design of it, but as a user, from my perspective the ability to serialize a pointer is kind of eagerly needed :) |
Right, you could use a simple wrapper type to bypass that, while waiting for a patch, if we decide to patch it. |
Yes, that is my plan, thanks. |
What exactly would need to be changed? |
It would require this // line 3651
template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0>
PointerType get() noexcept
{
// delegate the call to get_ptr
return get_ptr<PointerType>();
} |
Hm. This indeed breaks existing code. Of course there is the way to call |
The point is just to let users handle pointers as they see fit, the library would not have a default behaviour in this case. I'm not 100% sure we should make this change either, but I still think it's a good idea. For users relying on |
I reopen this and hope to get more input in the discussion. I currently do not see the point at all to store pointers inside JSON, so I don't really care about an elegant interface for this. |
As there is no more discussion. I close this issue for now. Breaking code without an explicit benefit seems to be a bad idea. |
Hey, My goal is to parse this map as member variable, where the BaseClass* represents an interface with virtual methods and i plug in different deriving types in there.
any idea how to make json resolve my pointers in an stl, before parsing them? |
edit: i had the idea, that i can overwrite the function which uses exactly this map like:
but in output my json looks like an array not like a map ( i want to get rid of the squared brackets)
what i actually want:
|
found the solution!
the trick is to understand the differnece between array and object for json. |
Recently I am thinking to have some thing like this,
Foo a, b, c;
json j=json(Array());
j.push_back(&a);
j.push_back(&b);
j.push_back(&c);
for(auto e: j){
//e would get a pointer to Foo class.
}
Is this possible to implement? I tried to_json and from_json , but seems the features are limited.
The text was updated successfully, but these errors were encountered: