I am trying to write and read json data of class object. Here is the code. I am using serialization/de-serialization using to_json()
and from_json()
. For non templated classes, things work fine, but facing issues for templated classes and structures. Below is the entire code example I am trying to build.
#include <vector>
#include <optional>
#include <iostream>
#include <memory>
#include <Eigen/Dense>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
template <class InputType = float, class OutputType = bool>
class Test {
public:
struct InputOutputPair {
InputType input;
OutputType output;
};
void SetLeftThreshold(InputType threshold) {
m_leftThreshold = threshold;
}
void SetRightThreshold(InputType threshold) {
m_rightThreshold = threshold;
}
void SetLeftOutput(InputType output) {
m_leftOutput = output;
}
void SetRightOutput(InputType output) {
m_rightOutput = output;
}
void SetThresholdsMidpoint(InputType midThreshold) {
m_thresholdsMidpoint = midThreshold;
}
void SetCurrentOutput(std::optional<OutputType> currentOutput) {
m_currentOutput.emplace(currentOutput.value());
}
private:
InputType m_leftThreshold;
InputType m_rightThreshold;
OutputType m_leftOutput;
OutputType m_rightOutput;
InputType m_thresholdsMidpoint;
std::optional<OutputType> m_currentOutput;
};
class Data {
public:
Test<> m_leftSwitch;
};
inline void from_json(const json& j, Data& hsd) {
j.at("isLeftSwitch").get_to(hsd.m_leftSwitch);
}
namespace nlohmann {
template <class InputType, class OutputType>
struct adl_serializer<Test<InputType, OutputType>> {
inline void from_json(const json& j, Test<InputType, OutputType>& hsd) {
hsd.SetLeftThreshold(j.at("leftThreshold"));
hsd.SetRightThreshold(j.at("rightThreshold"));
hsd.SetLeftOutput(j.at("leftOutput"));
hsd.SetRightOutput(j.at("rightOutput"));
hsd.SetThresholdsMidpoint(j.at("thresholdMidPoint"));
hsd.SetCurrentOutput(j.at("currentOutput"));
}
};
} // namespace nlohmann
int main() {
}
Demo example https://godbolt.org/z/j5Yv9xGd7
Issue - I get build errors as shown in the example
<source>:In function 'void nlohmann::to_json(json_v3_11_1::json&, const Data&)':
<source>:82:44: error: no match for 'operator=' (operand types are 'nlohmann::json_v3_11_1::json' {aka 'nlohmann::json_v3_11_1::basic_json<>'} and '<brace-enclosed initializer list>')
82 | j = {{"isLeftSwitch", hsd.m_leftSwitch}};
<source>: In function 'void nlohmann::from_json(const json_v3_11_1::json&, Data&)':
<source>:78:32: error: no matching function for call to 'nlohmann::json_v3_11_1::basic_json<>::get_to(Test<>&) const'
78 | j.at("isLeftSwitch").get_to(hsd.m_leftSwitch);
Question - Any pointers where I am going wrong in case of reading and writing templated classes using from and to json. Thank you.
According to the readme the adl_serializer
functions need to be static
.
It is implemented like this (simplified):
template <typename T> struct adl_serializer { static void to_json(json& j, const T& value) { // calls the "to_json" method in T's namespace } static void from_json(const json& j, T& value) { // same thing, but with the "from_json" method } };
Once I made that change to your demo example (and commented out the from_json code since you haven't implemented any Get*
functions yet) the code compiled.