-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
Non-member operator== breaks enum (de)serialization #1647
Comments
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Replying to keep this alive and kicking. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Alive and kicking bug, AFAIK. |
I can confirm the bug with GCC on macOS:
Strangely, the code compiles without issues using Clang. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Poking the bot. |
In msvc, enum in namespace can't serialze to json. Only change to these can fix this problom, but it enable when use basic json type. #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
inline void to_json(nlohmann::json& j, const ENUM_TYPE& e) \
{ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, nlohmann::json> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, nlohmann::json>& ej_pair) -> bool \
{ \
return ej_pair.first == e; \
}); \
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
} \
inline void from_json(const nlohmann::json& j, ENUM_TYPE& e) \
{ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, nlohmann::json> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[j](const std::pair<ENUM_TYPE, nlohmann::json>& ej_pair) -> bool \
{ \
return ej_pair.second == j; \
}); \
e = ((it != std::end(m)) ? it : std::begin(m))->first; \
} |
@pkngpkng I'm not quite sure what you're trying to say. Are you saying there's a bug in the |
@AnthonyVH Yes |
Any idea how to proceed here? |
define a new marco to serialize basic json type? @nlohmann #define NLOHMANN_BASIC_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
inline void to_json(nlohmann::json& j, const ENUM_TYPE& e) \
{ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, nlohmann::json> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, nlohmann::json>& ej_pair) -> bool \
{ \
return ej_pair.first == e; \
}); \
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
} \
inline void from_json(const nlohmann::json& j, ENUM_TYPE& e) \
{ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, nlohmann::json> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[j](const std::pair<ENUM_TYPE, nlohmann::json>& ej_pair) -> bool \
{ \
return ej_pair.second == j; \
}); \
e = ((it != std::end(m)) ? it : std::begin(m))->first; \
} |
* ⬆️ Doctest 2.4.7 * 👷 add CI step for ICPC * 👷 add CI step for ICPC * 👷 add CI step for ICPC * ⬇️ downgrade to Doctest 2.4.6 * 👷 add CI step for ICPC * 👷 add CI step for ICPC * 👷 add CI step for ICPC * 👷 add CI step for ICPC * 👷 add CI step for ICPC * 🔇 suppress warning #2196: routine is both "inline" and "noinline" * Re-enable <filesystem> detection on ICPC * Limit regression test for #3070 to Clang and GCC >=8.4 * Disable deprecation warnings on ICPC * Disable regression test for #1647 on ICPC (C++20) * Fix compilation failure of regression test for #3077 on ICPC * Disable wstring unit test on ICPC Fixes: error 913: invalid multibyte character sequence * Add ICPC to README Co-authored-by: Niels Lohmann <mail@nlohmann.me>
What is the issue you have?
Compile error when trying to (de)serialize an enum.
Please describe the steps to reproduce the issue. Can you provide a small but working code example?
AFAIK the minimum requirement to trigger this is:
non-member operator== is defined.
MWE (Wandbox), see code below.
Again AFAIK, this is what happens: the comparisons in NLOHMANN_JSON_SERIALIZE_ENUM on lines 571 and 583 are against different types (BasicJsonType & ENUM_TYPE). This causes the compiler to try and convert both sides to a common type. Since there's a non-member
operator==
fordummy::foo
, it will try to convert both sides todummy::foo
. And since to/from_json has been defined, it tries to use that to deserialize the JSON. It seems that for some reason the wrongget<dummy::foo>()
is called, which then gives a compile error. That's as far as I got, I haven't had more time to try and debug all the template code.PS: Seems to me the capture
[j]
on line 581 should be[&j]
, the JSON object is being copied right now.What is the expected behavior?
Code compiles and (de)serializes enums properly.
And what is the actual behavior instead?
The code gives a compile error.
Which compiler and operating system are you using? Is it a supported compiler?
Tried with gcc 7.3.0 and gcc 9.1.0 (on Wandbox).
Did you use a released version of the library or the version from the
develop
branch?Release 3.6.1, single header version.
If you experience a compilation error: can you compile and run the unit tests?
I haven't gotten around to this. If it helps I can try that this weekend.
The text was updated successfully, but these errors were encountered: