Skip to content
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

.get() throws error if used with userdefined structs in unordered_map #1448

Closed
MagicTripz opened this issue Jan 20, 2019 · 3 comments
Closed
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@MagicTripz
Copy link

MagicTripz commented Jan 20, 2019

  • What is the issue you have?
    I'm trying to save a unordered_map<int,struct> to a json and after that convert it back to the same unordred_map. Saving it works fine, the output is as expected but when i try to load the map from the given json this error is thrown : "JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));" (line 15402)."
    If i simply overlooked something then im very sorry to bother.

  • Please describe the steps to reproduce the issue. Can you provide a small but working code example?

struct Data
{
	bool bool1;
	bool bool2;
};

inline void from_json(const json& j, Data& config)
{
	config.bool1 = j.at("bool1").get < bool >();
	config.bool2 = j.at("bool2").get < bool >();
}
inline void to_json(json& j, const Data& config)
{
	j = json{
		{ "bool1", config.bool1 },
		{ "bool2", config.bool2 }
	};
}
void codeexample()
{
	//oversimplified example
	std::string key1, key2;//give them some random value 
	key1 = "fine1";
	key2 = "fine2";
	int integerofchoice = 1;
	std::unordered_map<int, Data> map =
	{
		{1,{true,false}},
		{2,{true,true}},
	};
	//saving it

	json Cfg;
	Cfg[key1][key2].push_back(map[integerofchoice]);
	//output is fine

       map[integerofchoice] = Cfg[key1][key2].get<Data>();//crashes 
        //step by step for debugging
	auto fine = Cfg.at(key1);
	auto fine2 = fine.at(key2);
	auto crash = fine2.at("bool1").get<bool>();



}
  • What is the expected behavior?
    .get<>() function should return bool1 and bool2 as from__json() is defined

  • And what is the actual behavior instead?
    Throws the error and crashes

  • Which compiler and operating system are you using? Is it a supported compiler?
    Msvc win10 newest build

  • Did you use a released version of the library or the version from the develop branch?
    release version 3.5.0

@nlohmann
Copy link
Owner

nlohmann commented Jan 21, 2019

Maps whose keys are not strings are converted to an array of pairs, because JSON objects must be strings. This seems to be the issue here. 

@nlohmann
Copy link
Owner

When you investigate Cfg after the push_back, you have the following value:

{"fine1":{"fine2":[{"bool1":true,"bool2":false}]}}

(Note the array at key fine2.)

This code then works:

auto d = Cfg[key1][key2][0].get<Data>();
map[integerofchoice] = d;

(Note the [0] to access the array element.)

Also, this works:

map[integerofchoice] = Cfg[key1][key2][0];

or this:

map[integerofchoice] = Cfg[key1][key2][0].get<Data>()

@nlohmann nlohmann added kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation labels Jan 21, 2019
@MagicTripz
Copy link
Author

MagicTripz commented Jan 21, 2019

It now works as expected, thank you very much! I overlooked the fact that the push_back made it an array, thought it would be the same as "=" my bad

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

2 participants