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

Cannot deserialize types using std::ratio #1105

Closed
GabrielDav opened this issue May 23, 2018 · 3 comments
Closed

Cannot deserialize types using std::ratio #1105

GabrielDav opened this issue May 23, 2018 · 3 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@GabrielDav
Copy link

Given
void from_json(const json& j, std::ratio<60>& r) { // parsing }
I expect to get parsed value back when used like this:
auto data = j.at("Data").get<std::ratio<60>>()
However, instead I'm getting a compilation error:

could not find from_json() method in T's namespace

This problem impacts usage of std::chrono::duration and std::crhono::time_point

This is really weird, because I copied implementation of std::ratio and renamed struct to rat

template<intmax_t _Nx,
		intmax_t _Dx = 1>
		struct rat
	{	// holds the ratio of _Nx to _Dx
		static_assert(_Dx != 0,
			"zero denominator");
		static_assert(-INTMAX_MAX <= _Nx,
			"numerator too negative");
		static_assert(-INTMAX_MAX <= _Dx,
			"denominator too negative");

		static constexpr intmax_t num = _Sign_of<_Nx>::value
			* _Sign_of<_Dx>::value * _Abs<_Nx>::value / _Gcd<_Nx, _Dx>::value;

		static constexpr intmax_t den = _Abs<_Dx>::value / _Gcd<_Nx, _Dx>::value;

		typedef rat<num, den> type;
	};

void from_json(const json& j, rat<60>& r)
	{
            // parsing
	}

auto data = j.at("Data").get<rat<60>>();

Surprisingly this works as expected.
I'm using Visual Studio 2017 msvc compiler. Project uses std::chrono across solution without any issues.

@nlohmann
Copy link
Owner

I think the reason for this is that the from_json function must be defined in the same namespace as the respective type. That's why it does not work for std::ratio, but for rat. Please have a look at https://github.com/nlohmann/json#arbitrary-types-conversions - there is an example how to deal with these situations by specializing adl_serializer.

@nlohmann nlohmann added kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation labels May 23, 2018
@GabrielDav
Copy link
Author

Works like charm. I can't believe I tried to solve 'the issue' and even opened new issue without reading documentation carefully. Sorry about that and thank you for pointing me to the right direction

@nlohmann
Copy link
Owner

No worries!

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