-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Description
Description
Converting a json object to an rvalue of a variant containing a type that can be constructed from a string and json itself, will result in construction of a variant with that string-constructible type, and crash if the json object does not contain a string. This even happens on a variant containing only nlohmann::json, as that type is both "constructible from string" and "nlohmann::json itself".
I suspect this is actually an MSVC compiler bug, but a workaround in the json library would be nice, if possible.
Reproduction steps
Given
using var = std::variant<nlohmann::json>;
std::vector<var> vars;
run
vars.push_back(nlohmann::json(1));
Expected vs. actual results
Actual: the call vars.push_back(json(1)) results in an assertion failure
Expected: a variant containing a json object containing the number 1 is pushed into the vector
The expected result occurs, because the json object does not contain a string. This happens because the type var is constructible from a string, and if MSVC requires a conversion from json to var &&, it prefers the route via template<typename T> T json::operator T() const over the route of creating a temporary variant being passed to push_back.
Minimal code example
#include <variant>
#include <vector>
#include <nlohmann/json.hpp>
int main()
{
std::vector<std::variant<nlohmann::json>> v;
v.push_back(nlohmann::json(1));
}Furthermore, I set up a demonstration for MSVC picking the unwanted conversion path without nlohmann::json on Compiler Explorer. I did not use the actual JSON library, because Compiler Explorer doesn't support external libraries on Windows. I tested locally using MSVC that the issue happens with the acutal JSON library in exactly the same way. See
https://godbolt.org/z/xP8r1nYT8 .
Error messages
The miminal example shown bove terminates with an assertion failure (`JSON_THROW`) with this backtrace:
nlohmann::detail::from_json<nlohman::json, std::variant<nlohmann::json>, 0>(const nlohman::json&, std::variant<nlohmann::json>&)
nlohmann::detail::from_json_fn::operator()<nlohmann::json, std::variant<nlohmann::json>&>(nlohmann::json&, std::variant<nlohmann::json>&)
nlohmann::adl_serializer<std::variant<nlohmann::json>, void>::from_json<const nlohmann::json &, std::variant<nlohmann::json>>(const nlohmann::json&, std::variant<nlohmann::json>>&)
nlohmann::json::get_impl<std::variant<nlohmann::json>, 0>(nlohmann::detail::priority_tag<0>)
nlohmann::json::get<std::variant<nlohmann::json>, std::variant<nlohmann::json>>()
nlohmann::json::operator<std::variant<nlohmann::json>, 0> std::variant<nlohmann::json>()
main()Compiler and operating system
Visual Studio 17.6.5 running on Microsoft Window 11 25H2
Library version
3.10.5
Validation
- The bug also occurs if the latest version from the
developbranch is used. - I can successfully compile and run the unit tests.