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
In file included from test.cpp:1:0:
fifo_map.hpp: In instantiation of 'nlohmann::fifo_map<Key, T, Compare, Allocator>::fifo_map() [with Key = std::__cxx11::basic_string<char>; T = nlohmann::basic_json<nlohmann::fifo_map>; Compare = std::less<std::__cxx11::basic_string<char> >; Allocator = std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::basic_json<nlohmann::fifo_map> > >]':
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/ext/new_allocator.h:120:4: required from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = nlohmann::fifo_map<std::__cxx11::basic_string<char>, nlohmann::basic_json<nlohmann::fifo_map>, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::basic_json<nlohmann::fifo_map> > > >; _Args = {}; _Tp = nlohmann::fifo_map<std::__cxx11::basic_string<char>, nlohmann::basic_json<nlohmann::fifo_map>, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::basic_json<nlohmann::fifo_map> > > >]'
json.hpp:1634:9: required from 'static T* nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::create(Args&& ...) [with T = nlohmann::fifo_map<std::__cxx11::basic_string<char>, nlohmann::basic_json<nlohmann::fifo_map>, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::basic_json<nlohmann::fifo_map> > > >; Args = {}; ObjectType = nlohmann::fifo_map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer'
json.hpp:1701:46: required from 'nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::json_value::json_value(nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::value_t) [with ObjectType = nlohmann::fifo_map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::value_t = nlohmann::detail::value_t]'
json.hpp:1917:49: required from 'nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::basic_json(nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::value_t) [with ObjectType = nlohmann::fifo_map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::value_t = nlohmann::detail::value_t]'
json.hpp:1941:35: required from 'nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::basic_json(std::nullptr_t) [with ObjectType = nlohmann::fifo_map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; std::nullptr_t = std::nullptr_t]'
test.cpp:8:10: required from here
fifo_map.hpp:126:63: error: no matching function for call to 'std::less<std::__cxx11::basic_string<char> >::less(std::unordered_map<std::__cxx11::basic_string<char>, long unsigned int, std::hash<std::__cxx11::basic_string<char> >, std::equal_to<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, long unsigned int> > >*)'
fifo_map() : m_keys(), m_compare(&m_keys), m_map(m_compare) {}
^
From Clang:
./fifo_map.hpp:126:28: fatal error: no matching constructor for initialization
of 'std::__1::less<std::__1::basic_string<char> >'
fifo_map() : m_keys(), m_compare(&m_keys), m_map(m_compare) {}
^ ~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1740:31: note:
in instantiation of member function
'nlohmann::fifo_map<std::__1::basic_string<char>,
nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer>,
std::__1::less<std::__1::basic_string<char> >,
std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>,
nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer> > > >::fifo_map' requested here
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
^
./json.hpp:1634:15: note: in instantiation of function template specialization
'std::__1::allocator<nlohmann::fifo_map<std::__1::basic_string<char>,
nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer>,
std::__1::less<std::__1::basic_string<char> >,
std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>,
nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer> > > >
>::construct<nlohmann::fifo_map<std::__1::basic_string<char>,
nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer>,
std::__1::less<std::__1::basic_string<char> >,
std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>,
nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer> > > >>' requested here
alloc.construct(object.get(), std::forward<Args>(args)...);
^
./json.hpp:1701:30: note: in instantiation of function template specialization
'nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator,
adl_serializer>::create<nlohmann::fifo_map<std::__1::basic_string<char>,
nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer>,
std::__1::less<std::__1::basic_string<char> >,
std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>,
nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer> > > >>' requested here
object = create<object_t>();
^
./json.hpp:1917:31: note: in instantiation of member function
'nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer>::json_value::json_value' requested here
: m_type(value_type), m_value(value_type)
^
./json.hpp:1941:11: note: in instantiation of member function
'nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer>::basic_json' requested here
: basic_json(value_t::null)
^
test.cpp:8:10: note: in instantiation of member function
'nlohmann::basic_json<nlohmann::fifo_map, std::vector,
std::__1::basic_string<char>, bool, long long, unsigned long long, double,
std::allocator, adl_serializer>::basic_json' requested here
json j;
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:59:30: note:
candidate constructor (the implicit copy constructor) not viable: no known
conversion from 'std::unordered_map<basic_string<char>, std::size_t> *'
(aka 'unordered_map<std::__1::basic_string<char>, unsigned long> *') to
'const std::__1::less<std::__1::basic_string<char> >' for 1st argument
struct _LIBCPP_TYPE_VIS_ONLY less : binary_function<_Tp, _Tp, bool>
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:59:30: note:
candidate constructor (the implicit move constructor) not viable: no known
conversion from 'std::unordered_map<basic_string<char>, std::size_t> *'
(aka 'unordered_map<std::__1::basic_string<char>, unsigned long> *') to
'std::__1::less<std::__1::basic_string<char> >' for 1st argument
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:59:30: note:
candidate constructor (the implicit default constructor) not viable:
requires 0 arguments, but 1 was provided
1 error generated.
I can confirm the error, but I have no idea how to fix it. I haven't tried fifo_map for this issue in a long time - I only mentioned it in the REAMDE, because I read somewhere that it was used successfully with this library. There may be issues, because fifo_map uses std::unordered_map internally, which is problematic (#164).
Hi, I think I found out the problem, I think it's because when you are declaring object_t,
you use std::less, but not all map-like use std::less, i'm guessing it's because you wanted to set the allocator.
I can offer a patch: Patch (might break people who set the map manually)
If you still want to keep you inner type allocator aware
template<class K, class V, class A>
using default_object_t = std::map<K, V, std::less< K >, A>; // A wrapper class for the new usage
template <
template<typename U, typename V, typename... Args> class ObjectType = default_object_t,
...
>
class basic_json
{
using object_t = ObjectType<StringType,
basic_json,
AllocatorType<std::pair<const StringType,
basic_json>>>; // Note I removed std::less
}
now if you want to use fifo_map you can by using the follow:
template<class K, class V, class A>
using my_obj = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare< K >, A>;
template<class K, class V, class A>
using my_obj2 = std::unordered_map<K, V, std::hash< K >, std::equal_to< K >, A>; // Can support also unordered_map
using my_json = nlohmann::basic_json<my_obj>;
please note that I haven't fully tested it, just basic example, not sure if it's the right way to do it, just an idea.
Also I can offer a workaround without changing the json library itself but it's a bit more ugly and will break if you will fix it using the patch above.
Let me know if you want this patch a pull request.
The fifo_map library uses an uncommon comparator type, which needs to hold a key storage. std::map for example uses std::less by default, which is a simple functor without state.
The json library follows the pattern of std::map which directly passes std::less<StringType> to the object type. And of course, there is no constructor for std::less<std::string>(std::unordered_map<Key, std::size_t>*). That's the problem.
It is not possible to solve this without breaking compatibility with one of the libraries.
As I said before in my previous comment, there is a way to do it without a change in the libraries, it's a workaround which I don't like that much since it will break if the API will change.
anyway here it's: (be warn - this workaround will break if the template parameters will change)
#include"json.hpp"
#include"fifo_map.hpp"
#include<iostream>usingnamespacenlohmann;// A workaround to give to use fifo_map as map, we are just ignoring the 'less' comparetemplate<classK, classV, classdummy_compare, classA>
using my_workaround_fifo_map = fifo_map<K, V, fifo_map_compare<K>, A>;
using my_json = basic_json<my_workaround_fifo_map>;
intmain()
{
my_json j;
j["f"] = 5;
j["a"] = 2;
my_json j2 = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {
{"everything", 42}
}},
{"list", {1, 0, 2}},
{"object", {
{"currency", "USD"},
{"value", 42.99}
}}
};
std::cout << j << std::endl;
std::cout << j2 << std::endl;
return0;
}
I don't like this workaround very much since it isn't clean and really patchy, but maybe this will give others a better idea about what to do.
Reacted by Niels Lohmann, Pär Winzell, kyb, George Samartzidis, Niklas Schnelle, Justin Briggs, Li Zhang, Mikhail Khalizev, Wuson, Bren Ochoa and 2 more
it doesn't compile because they are different types.
if you want same function for both of them, you need to convert processJson into a template function:
I am sorry if this has been already solved, but I am trying to build specialized json with fifo_map, using following code:
#include<nlohmann/json.hpp>
#include<nlohmann/fifo_map.hpp>// for convenienceusing json = nlohmann::basic_json<nlohmann::fifo_map>;
and I am hit by the error already reported by @arvidsson above:
C:\PROGRA~2\MICROS~2\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\HostX64\x64\cl.exe /nologo /TP -ID:\Dev\include\xtensor -ID:\Dev\include\nlohmann -ID:\Dev\include /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 -std:c++17 /showIncludes /Fohmdq\CMakeFiles\hmdq.dir\hmdq.cpp.obj /Fdhmdq\CMakeFiles\hmdq.dir\ /FS -c ..\..\hmdq\hmdq.cpp
D:\Dev\include\nlohmann\fifo_map.hpp(188): error C2039: 'add_key': is not a member of 'std::less<void>'
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\xstddef(278): note: see declaration of 'std::less<void>'
D:\Dev\include\nlohmann/fifo_map.hpp(187): note: while compiling class template member function 'T &nlohmann::fifo_map<StringType,T,nlohmann::basic_json<nlohmann::fifo_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>::object_comparator_t,std::allocator<std::pair<const StringType,nlohmann::basic_json<nlohmann::fifo_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>>::operator [](const Key &)'
with
[
T=nlohmann::basic_json<nlohmann::fifo_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>,
StringType=std::string,
Key=std::string
]
D:\Dev\include\nlohmann/json.hpp(3130): note: see reference to function template instantiation 'T &nlohmann::fifo_map<StringType,T,nlohmann::basic_json<nlohmann::fifo_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>::object_comparator_t,std::allocator<std::pair<const StringType,nlohmann::basic_json<nlohmann::fifo_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>>::operator [](const Key &)' being compiled
with
[
T=nlohmann::basic_json<nlohmann::fifo_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>,
StringType=std::string,
Key=std::string
]
D:\Dev\include\nlohmann/json.hpp(15909): note: see reference to class template instantiation 'nlohmann::fifo_map<StringType,nlohmann::basic_json<nlohmann::fifo_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>,nlohmann::basic_json<nlohmann::fifo_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>::object_comparator_t,std::allocator<std::pair<const StringType,nlohmann::basic_json<nlohmann::fifo_map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>>' being compiled
with
[
StringType=std::string
]
..\..\hmdq\hmdq.cpp(50): note: see reference to class template instantiation 'nlohmann::basic_json<nlohmann::fifo_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>' being compiled
ninja: build stopped: subcommand failed.
I wonder, was it resolved, or is it a know bug? If the latter, is there any other solution?
@risa2000 it doesn't seems like you used my workaround.
please define your json type as the example below.
As I said before in my previous comment, there is a way to do it without a change in the libraries, it's a workaround which I don't like that much since it will break if the API will change.
anyway here it's: (be warn - this workaround will break if the template parameters will change)
#include"json.hpp"
#include"fifo_map.hpp"
#include<iostream>usingnamespacenlohmann;// A workaround to give to use fifo_map as map, we are just ignoring the 'less' comparetemplate<classK, classV, classdummy_compare, classA>
using my_workaround_fifo_map = fifo_map<K, V, fifo_map_compare<K>, A>;
using my_json = basic_json<my_workaround_fifo_map>;
intmain()
{
my_json j;
j["f"] = 5;
j["a"] = 2;
my_json j2 = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {
{"everything", 42}
}},
{"list", {1, 0, 2}},
{"object", {
{"currency", "USD"},
{"value", 42.99}
}}
};
std::cout << j << std::endl;
std::cout << j2 << std::endl;
return0;
}
@Daniel599 thanks for the nudge. Indeed I did not apply the "fix" as I did not understand that it was one! After following your example, it works as expected. Unfortunately, it turned out that I am stuck anyway.
The reason is that I am using xtensor library in the same project, which implements also a serialization/deserialization through nlohmann::json, but this library seems to be "hardcoding" nlohmann::json as the type it uses everywhere, with no template for possible specialization with a custom mapping class. So I guess I am going to write another report over there.
I am currently trying to generate JSON with ordered keys and therefore used the workaround method from @Daniel599 . I just copy-pasted your workaround code and it worked as aspected. However, if I try to use it within my base and derived classes, I get an error which I do not really understand. It seems like it fails to call the to_Json methods (because the error appears if I try to map a DerivedClass-instance (test and test2) to my_json.
I have already tried the example without ordered keys (just by using json = nlohmann::json;) and it works completely fine. The keys in the output are sorted alphabetically and looks like this:
Error C2440: 'initializing': cannot convert from 'BaseNamespace::SubNamespace::DerivedClass' to 'nlohmann::basic_json<my_workaround_fifo_map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>' ; in file: main.cpp
Please have a look at the following code:
In BaseClass.h:
#ifndef BASECLASS_H
#define BASECLASS_H
#include <stdint.h>
#include <string>
#include "nlohmann/json.hpp"
#include "fifo_map.hpp"
namespace BaseNamespace{
namespace SubNamespace{
class BaseClass {
public:
BaseClass () {};
virtual ~BaseClass () {};
uint32_t getHeaderId() const { return headerId; };
std::string getTimestamp() const { return timestamp; };
std::string getVersion() const { return version; };
void setHeaderId(uint32_t str) { headerId = str; };
void setTimestamp(std::string str) { timestamp = str; };
void setVersion(std::string bo) { version = bo; };
void setHeader(UAgvHeader const& header) {
setHeaderId(header.getHeaderId());
setTimestamp(header.getTimestamp());
setVersion(header.getVersion());
}
private:
uint32_t headerId;
std::string timestamp;
std::string version;
};
// A workaround to give to use fifo_map as map, we are just ignoring the 'less' compare
using namespace nlohmann;
template<class K, class V, class dummy_compare, class A>
using my_workaround_fifo_map = fifo_map<K, V, fifo_map_compare<K>, A>;
using my_json = basic_json<my_workaround_fifo_map>;
void to_json(my_json &j, const BaseClass &p)
{
j = my_json{
{ "headerId", p.getHeaderId() },
{ "timestamp", p.getTimestamp() },
{ "version", p.getVersion() }
};
}
void from_json(const my_json &j, BaseClass &p)
{
p.setHeaderId(j.at("headerId").get< std::uint32_t>());
p.setTimestamp(j.at("timestamp").get< std::string >());
p.setVersion(j.at("version").get<std::string>());
}
} // namespace SubNamespace
} // namespace BaseNamespace
#endif // BASECLASS_H_
In DerivedClass.h:
#ifndef DERIVEDCLASS_H
#define DERIVEDCLASS_H
#include <stdint.h>
#include <string>
#include "nlohmann/json.hpp"
#include <optional>
#include "BaseClass.h"
namespace BaseNamespace{
namespace SubNamespace{
class DerivedClass : public BaseClass {
public:
std::string getCBor() const { return cbor; };
std::string getHex() const { return hex; };
bool getRoundtrip() const { return roundtrip; };
std::optional<std::string> getDiagnostic() const { return diagnostic; };
void setCBor(std::string str) { cbor = str; };
void setHex(std::string str) { hex = str; };
void setRoundtrip(bool bo) { roundtrip = bo; };
void setDiagnostic(std::optional<std::string> opt_str) { diagnostic = opt_str; };
private:
std::string cbor;
std::string hex;
bool roundtrip;
std::optional<std::string> diagnostic = std::nullopt;
};
void to_json(my_json &j, const DerivedClass& p)
{
j["header"] = static_cast<BaseClass>(p);
j["cbor"] = p.getCBor();
j["hex"] = p.getHex();
j["roundtrip"] = p.getRoundtrip();
// assuming you only want a "diagnostic" key if there is an actual value;
// if not, store a nullptr and adjust the from_json accordingly
if (p.getDiagnostic() != std::nullopt)
{
j["diagnostic"] = p.getDiagnostic().value();
}
}
void from_json(const my_json &j, DerivedClass&p)
{
p.setHeader(j.at("header").get<BaseClass>());
p.setCBor(j.at("cbor").get< std::string >());
p.setHex(j.at("hex").get< std::string >());
p.setRoundtrip(j.at("roundtrip").get< bool >());
// if we also allow "null" values, then we need to add an "is_string()"
// check
if (j.count("diagnostic") != 0)
{
p.setDiagnostic(j.at("diagnostic").get< std::string >());
}
}
} // namespace SubNamespace
} // namespace BaseNamespace
#endif // DERIVEDCLASS_H
In main.cpp:
#include <iostream>
#include <string>
#include <nlohmann/json.hpp>
#include <iomanip>
#include <optional>
#include "DerivedClass.h"
using namespace nlohmann;
// A workaround to give to use fifo_map as map, we are just ignoring the 'less' compare
template<class K, class V, class dummy_compare, class A>
using my_workaround_fifo_map = fifo_map<K, V, fifo_map_compare<K>, A>;
using my_json = basic_json<my_workaround_fifo_map>;
int main(int argc, char* argv[]) {
BaseNamespace::SubNamespace::DerivedClass test;
test.setHeaderId(3);
test.setTimestamp("2019-12-10T16:04:00.00Z");
test.setVersion("4.0.0");
test.setCBor("cbortest");
test.setHex("00f2");
test.setRoundtrip(true);
test.setDiagnostic("diagnose: corona");
my_json j = test; // ERROR: no suitable conversion
std::cout << std::setw(2) << j << std::endl;
std::string str = R"({"header":
{ "headerId" : 4711,
"timestamp" : "1 Uhr",
"version" : "5.0.0"
},
"cbor" : "+X4A",
"hex" : "f97e00",
"roundtrip" : true,
"diagnostic" : "NaN"
})";
my_json j2 = my_json::parse(str);
BaseNamespace::SubNamespace::DerivedClass test2 = j2;
my_json k = test2; // ERROR: no suitable conversion
std::cout << std::setw(2) << k << std::endl;
return 0;
}
Hi @theresa95, after some investigation I found out the cause of your error is due to multiple "my_json" types: one inside BaseNamespace::SubNamespace::my_json and the other in the global scope.
I don't know if it's the same case in your original code, but I mange to fix it by doing the following:
remove using namespace nlohmann; within your namespace (e.g inside BaseClass.h & DerivedClass.h)
define my_json in single place at BaseClass.h
after doing the steps above, your code example compiles on g++ 7.5 with -std=c++17, I hope it compiles on windows as well (if not let me know)
Hey @Daniel599 , first of all, thank you for the quick answer!
I edited the codesnippet of my question to fit your answer.
I removed the following lines from the DerivedClass.h file:
using namespace nlohmann;
template<class K, class V, class dummy_compare, class A>
using my_workaround_fifo_map = fifo_map<K, V, fifo_map_compare<K>, A>;
using my_json = basic_json<my_workaround_fifo_map>;
But I still get the same error messages in the main.cpp file:
Removing the "using namespace nlohmann" in the BaseClass.h file results in other errors so I have left it there:
What should I do with my_json definition and using namespace nlohmann in the main.cpp file?
namespace BaseNamespace{
namespace SubNamespace{
// Other code
// A workaround to give to use fifo_map as map, we are just ignoring the 'less' compare
template<class K, class V, class dummy_compare, class A>
using my_workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
using my_json = nlohmann::basic_json<my_workaround_fifo_map>;
}
}
note the addition of nlohmann:: which is needed when you remove the using namespace nlohmann
in main.cpp:
you can keep the using namespace nlohmann but I would recommend against it, prefer to use nlohmann::blabla whenever you need (P.S I don't think you need it in main anymore anyway)
replace my_json with BaseNamespace::SubNamespace::my_json
a bit more details:
since my_json is declared inside the namespace BaseNamespace::SubNamespace and main isn't (it's in the global scope), you have two options: add the namespace prefix or add using namespace BaseNamespace::SubNamespace in main.cpp, I like more the first option since it's more explicit about where things are taken from.
Activity
nlohmann commentedon Mar 7, 2017
Can you please provide the compiler error messages?
adah1972 commentedon Mar 7, 2017
From GCC:
From Clang:
nlohmann commentedon Mar 7, 2017
Thanks, I shall have a look.
nlohmann commentedon Mar 7, 2017
I can confirm the error, but I have no idea how to fix it. I haven't tried
fifo_mapfor this issue in a long time - I only mentioned it in the REAMDE, because I read somewhere that it was used successfully with this library. There may be issues, becausefifo_mapusesstd::unordered_mapinternally, which is problematic (#164).arvidsson commentedon Apr 4, 2017
Using Visual Studio C++ 2017, I get the following error:
'add_key': is not a member of 'std::less'
Daniel599 commentedon Apr 10, 2017
Hi, I think I found out the problem, I think it's because when you are declaring object_t,
you use std::less, but not all map-like use std::less, i'm guessing it's because you wanted to set the allocator.
I can offer a patch:
Patch (might break people who set the map manually)
If you still want to keep you inner type allocator aware
now if you want to use fifo_map you can by using the follow:
please note that I haven't fully tested it, just basic example, not sure if it's the right way to do it, just an idea.
Also I can offer a workaround without changing the json library itself but it's a bit more ugly and will break if you will fix it using the patch above.
Let me know if you want this patch a pull request.
donho commentedon Sep 10, 2017
Same error under VS2015.
I think I will use nlohmann::json without fifo_map :(
nlohmann commentedon Sep 10, 2017
Related to #660 (comment):
I really need to remove the hint to fifo_map from the documentation... :-(
tomtachi commentedon Sep 10, 2017
tomtachi commentedon Sep 10, 2017
SiebelsTim commentedon Oct 2, 2017
The fifo_map library uses an uncommon comparator type, which needs to hold a key storage.
std::mapfor example usesstd::lessby default, which is a simple functor without state.The json library follows the pattern of
std::mapwhich directly passesstd::less<StringType>to the object type. And of course, there is no constructor forstd::less<std::string>(std::unordered_map<Key, std::size_t>*). That's the problem.It is not possible to solve this without breaking compatibility with one of the libraries.
Daniel599 commentedon Oct 2, 2017
As I said before in my previous comment, there is a way to do it without a change in the libraries, it's a workaround which I don't like that much since it will break if the API will change.
anyway here it's: (be warn - this workaround will break if the template parameters will change)
output:
I don't like this workaround very much since it isn't clean and really patchy, but maybe this will give others a better idea about what to do.
20 remaining items
Daniel599 commentedon Oct 26, 2018
it doesn't compile because they are different types.
if you want same function for both of them, you need to convert
processJsoninto a template function:risa2000 commentedon Jul 10, 2019
I am sorry if this has been already solved, but I am trying to build specialized
jsonwithfifo_map, using following code:and I am hit by the error already reported by @arvidsson above:
I wonder, was it resolved, or is it a know bug? If the latter, is there any other solution?
Daniel599 commentedon Jul 20, 2019
@risa2000 it doesn't seems like you used my workaround.
please define your json type as the example below.
risa2000 commentedon Jul 20, 2019
@Daniel599 thanks for the nudge. Indeed I did not apply the "fix" as I did not understand that it was one! After following your example, it works as expected. Unfortunately, it turned out that I am stuck anyway.
The reason is that I am using
xtensorlibrary in the same project, which implements also a serialization/deserialization throughnlohmann::json, but this library seems to be "hardcoding" nlohmann::json as the type it uses everywhere, with no template for possible specialization with a custom mapping class. So I guess I am going to write another report over there.theresa95 commentedon Apr 1, 2020
hey @nlohmann and @Daniel599 !
I am currently trying to generate JSON with ordered keys and therefore used the workaround method from @Daniel599 . I just copy-pasted your workaround code and it worked as aspected. However, if I try to use it within my base and derived classes, I get an error which I do not really understand. It seems like it fails to call the to_Json methods (because the error appears if I try to map a DerivedClass-instance (test and test2) to my_json.
I have already tried the example without ordered keys (just by using json = nlohmann::json;) and it works completely fine. The keys in the output are sorted alphabetically and looks like this:
What I am trying to achieve through using the nlohmann fifo_map is to keep the insertion order and the final output therefore should look like this:
Executing the following code outputs two errors:
Please have a look at the following code:
In BaseClass.h:
In DerivedClass.h:
In main.cpp:
Daniel599 commentedon Apr 1, 2020
Hi @theresa95, after some investigation I found out the cause of your error is due to multiple "my_json" types: one inside
BaseNamespace::SubNamespace::my_jsonand the other in the global scope.I don't know if it's the same case in your original code, but I mange to fix it by doing the following:
using namespace nlohmann;within your namespace (e.g inside BaseClass.h & DerivedClass.h)my_jsonin single place atBaseClass.hafter doing the steps above, your code example compiles on
g++ 7.5with-std=c++17, I hope it compiles on windows as well (if not let me know)theresa95 commentedon Apr 1, 2020
Hey @Daniel599 , first of all, thank you for the quick answer!
I edited the codesnippet of my question to fit your answer.
I removed the following lines from the DerivedClass.h file:
But I still get the same error messages in the main.cpp file:

Removing the "using namespace nlohmann" in the BaseClass.h file results in other errors so I have left it there:

What should I do with my_json definition and using namespace nlohmann in the main.cpp file?
Thank you so much for your help in advance!
Daniel599 commentedon Apr 1, 2020
@theresa95
in BaseClass.h:
note the addition of
nlohmann::which is needed when you remove theusing namespace nlohmannin main.cpp:
using namespace nlohmannbut I would recommend against it, prefer to usenlohmann::blablawhenever you need (P.S I don't think you need it in main anymore anyway)my_jsonwithBaseNamespace::SubNamespace::my_jsona bit more details:
since
my_jsonis declared inside the namespaceBaseNamespace::SubNamespaceandmainisn't (it's in the global scope), you have two options: add thenamespace prefixor addusing namespace BaseNamespace::SubNamespaceinmain.cpp, I like more the first option since it's more explicit about where things are taken from.theresa95 commentedon Apr 1, 2020
@Daniel599 That did the trick! Thank you so much!
nlohmann commentedon Jul 30, 2021
@ccpearson Thanks for sharing. I am confused - is
fifo_mapbroken with the latest release? We useobject_comparator_tnow.