Repository navigation
adl_serializer and CRTP #680
Copy link
Copy link
Closed
Labels
solution: proposed fixa fix for the issue has been proposed and waits for confirmationa fix for the issue has been proposed and waits for confirmation
Description
Because I really hate defining to_json/from_json by using the infamous ADL trick (I come from a C#/Java background so the fame of ADL depends), I decided to make the OOP-way-of-serialization shim of my own
I was having some progress, the following code demonstrated is a complete valid and legit code:
IJsonSerializable.hpp:
template<class T>
struct IJsonSerializable {
using self_t = IJsonSerializable<T>;
constexpr void to_json(json &j) const {
auto self = const_cast<self_t *>(this);
static_cast<T *>(self)->to_json(j);
}
constexpr void from_json(json &j) const {
auto self = const_cast<self_t *>(this);
static_cast<T *>(self)->from_json(j);
}
};
template <class T>
constexpr void to_json(json &j, const IJsonSerializable<T> *value) {
value->to_json(j);
}
template <class T>
constexpr void from_json(const json &j, IJsonSerializable<T> *value) {
auto _j = const_cast<json &>(j);
value->from_json(_j);
}
template <class T>
constexpr void to_json(json &j, const IJsonSerializable<T> &value) {
value.to_json(j);
}
template <class T>
constexpr void from_json(const json &j, IJsonSerializable<T> &value) {
auto _j = const_cast<json &>(j);
value.from_json(_j);
}Vector3.hpp:
#include "IJsonSerializable.h"
struct Vector3 : public IJsonSerializable<Vector3> {
float x, y, z;
public:
void to_json(json &j) {
j = {
{ "x", x },
{ "y", y },
{ "z", z}
};
}
void from_json(json &j) {
x = j["x"];
y = j["y"];
z = j["z"];
}
};This works pretty much fine for me, but is there any way to rewrite it in the following form?
namespace nlohmann {
template <class T>
struct adl_serializer<IJsonSerializable<T>> { // not working, should I insert SFINAE here?
using self_t = IJsonSerializable<T>;
constexpr void to_json(json &j, const self_t *value) {
value->to_json(j);
}
constexpr void from_json(const json &j, self_t *value) {
auto _j = const_cast<json &>(j);
value->from_json(_j);
}
constexpr void to_json(json &j, const self_t &value) {
value.to_json(j);
}
constexpr void from_json(const json &j, self_t &value) {
auto _j = const_cast<json &>(j);
value.from_json(_j);
}
};
}I group all my other serializers into namespace nlohmann just to keep it away from polluting my global namespace without creating another namespace of my own.
Metadata
Metadata
Assignees
Labels
solution: proposed fixa fix for the issue has been proposed and waits for confirmationa fix for the issue has been proposed and waits for confirmation
Activity
theodelrieu commentedon Aug 8, 2017
I'll take a look once I arrive to work, what if you replace
self_t*with a reference?We do not support pointers in
from/to_jsonat the moment.EDIT: also you must declare
adl_serializermethods asstatic, it will not work otherwise.theodelrieu commentedon Aug 12, 2017
Hi, just checking back, the code works on my laptop when adding
staticin front of both methods.By the way, you can remove both overloads that take
self_t *, they will never be called by the library.nlohmann commentedon Aug 15, 2017
Can I close this issue?