You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Please post example of specialization for boost::filesystem #692
Thanks for the response!
This produces:
explicit specialization; 'nlohmann::adl_serializer<T,void>' has already been instantiated
explicit specialization; 'nlohmann::adl_serializer<T,void>' has already been defined
In your case, the library already instantiated the default adl_serializer with boost::filesystem::path.
The reason why you don't see the usual static_assert trigger is due to complex template machinery.
I think that if you comment out your specialization, you will see a message saying:
Ok, if I comment out the section as you did, I get the same error about already instantiated/defined.
Also, I had a separate file for this specialization of a third-party library, however I did also have to_json and from_json methods in my own classes, and those methods exist alongside their respective class files.
So, there is indeed a slightly non-basic interaction in my case, because my custom classes have filesystem::path members. So, when I convert my classes to JSON, their to_json methods try to convert filesystem::path members to json, which implicitly should call the to_json from the specialization above.
Below is one of those classes. Interestingly, I just discovered that when I added the ADL_Specialization, the specialization logic, the below fails to compile now.
The question is, how does one organize specializations of both custom classes and third-party classes when the former depends on the latter. Do I have to aggregate all my custom class specialization methods into one big header along with the third-party ones?
Oh, I meant you needed to comment the whole specialization to see the static_assert, not the part I did comment in the example code, sorry about that.
I don't know how many third party classes you need to specialize adl_serializer for, with only two or three, you could put them in a single header (e.g json_boost.hpp).
As for your custom types that use third party types, you MUST include the header json_boost.hppbefore the definitions of to_json/from_json.
Finally, if you have to specialize adl_serializer for some of your types (e.g. a template custom container), it's up to you whether to put them in their own headers or in one big. Your types that provide ADL from_json/to_json will need to include them as for third-party types.
Ok, finally got it working. It does seem it was a result of my lack of experience in C++.
I did not realize I had to add the #include my json_adl_specialization.hpp file to any file that needs to serialize/deserialize any of the third-party types I've specialized. It makes sense now, but I thought that somehow the nlohmann library would automatically find and use my json_adl_specialization.hpp file because it had the nlohmann namespace. This is because I come from other languages, but also because much of what this library does seems like magic ;)
So, maybe it's worth updating the README documentation to explain that part about including the json_adl_specialization.hpp along with json.hpp in the section about specializing for third-party types. Maybe that's obvious to most C++ developers though, not sure.
Activity
nlohmann commentedon Aug 11, 2017
Did you put the struct into the
nlohmannnamespace?nlohmann commentedon Aug 11, 2017
I realized you pass the JSON value
jtoboost::filesystem::pathin youfrom_jsonfunction.This may work:
solvingj commentedon Aug 11, 2017
Thanks for the response!
This produces:
explicit specialization; 'nlohmann::adl_serializer<T,void>' has already been instantiated
explicit specialization; 'nlohmann::adl_serializer<T,void>' has already been defined
theodelrieu commentedon Aug 11, 2017
Hello,
This means you specialized the
adl_serializerafter one piece of code usingfilesystem::pathaltogether withnlohmann::json.You should specialize
adl_serializerinside a header that only contains such specializations:In your case, the library already instantiated the default
adl_serializerwithboost::filesystem::path.The reason why you don't see the usual
static_asserttrigger is due to complex template machinery.I think that if you comment out your specialization, you will see a message saying:
solvingj commentedon Aug 11, 2017
Ok, if I comment out the section as you did, I get the same error about already instantiated/defined.
Also, I had a separate file for this specialization of a third-party library, however I did also have
to_jsonandfrom_jsonmethods in my own classes, and those methods exist alongside their respective class files.So, there is indeed a slightly non-basic interaction in my case, because my custom classes have
filesystem::pathmembers. So, when I convert my classes to JSON, theirto_jsonmethods try to convert filesystem::path members to json, which implicitly should call theto_jsonfrom the specialization above.Below is one of those classes. Interestingly, I just discovered that when I added the ADL_Specialization, the specialization logic, the below fails to compile now.
The question is, how does one organize specializations of both custom classes and third-party classes when the former depends on the latter. Do I have to aggregate all my custom class specialization methods into one big header along with the third-party ones?
theodelrieu commentedon Aug 11, 2017
Oh, I meant you needed to comment the whole specialization to see the
static_assert, not the part I did comment in the example code, sorry about that.I don't know how many third party classes you need to specialize
adl_serializerfor, with only two or three, you could put them in a single header (e.gjson_boost.hpp).As for your custom types that use third party types, you MUST include the header
json_boost.hppbefore the definitions ofto_json/from_json.Finally, if you have to specialize
adl_serializerfor some of your types (e.g. a template custom container), it's up to you whether to put them in their own headers or in one big. Your types that provide ADLfrom_json/to_jsonwill need to include them as for third-party types.solvingj commentedon Aug 11, 2017
Ok, finally got it working. It does seem it was a result of my lack of experience in C++.
I did not realize I had to add the
#includemyjson_adl_specialization.hppfile to any file that needs to serialize/deserialize any of the third-party types I've specialized. It makes sense now, but I thought that somehow the nlohmann library would automatically find and use myjson_adl_specialization.hppfile because it had thenlohmannnamespace. This is because I come from other languages, but also because much of what this library does seems like magic ;)So, maybe it's worth updating the README documentation to explain that part about including the
json_adl_specialization.hppalong withjson.hppin the section about specializing for third-party types. Maybe that's obvious to most C++ developers though, not sure.theodelrieu commentedon Aug 11, 2017
Yes I agree, the doc needs some clarifications for those use-cases!