Unsure why my std::variant is serialising but not deserialising...? #2242
-
|
Can anyone please help? I'm trying to use Glaze to serialise and deserialise a std::variant (VariantStore in the fragment below). The serialisation works fine, but calling read_json() to try to deserialise from "world" gives error_code 34, i.e. no_matching_variant_type (I believe). I get the same error_code if I set the value to (int) 12345678, so it doesn't seem to be to do with std::string usage. All my other Glaze calls work fine: I'm using v5.0.0. Any ideas? Apologies if it's something really obvious! Thanks! EDIT: I suspect that this works under recent gcc (e.g. 13.3.0), but fails on my embedded device's compiler (gcc 12.3.0). If this is correct, is there a glz::custom workaround? This is with -std=c++23 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
|
Thanks for sharing this detailed report! The issue is that Glaze v5.0.0 doesn't support auto-deduction for variants with multiple types of the same JSON category. Your variant has three array types: std::vector<int>, std::vector<float>, std::vector<std::string>All three serialize to JSON arrays, and in v5.0.0, Glaze couldn't distinguish between them during deserialization. This was fixed in v5.6.1 with the addition of parsability-based variant support (#1916). With this feature, Glaze tries each variant alternative in order until one successfully parses. SolutionUpgrade to Glaze v5.6.1 or later (v7.0.0 is current). Your code should work without any changes: using VariantStore = std::variant<
bool, int, float, std::string,
std::vector<int>, std::vector<float>,
std::vector<std::string>
>;
VariantStore v;
glz::read_json(v, "[1, 2, 3]"); // → std::vector<int>
glz::read_json(v, "[1.5, 2.5]"); // → std::vector<float>
glz::read_json(v, R"(["a", "b"])"); // → std::vector<std::string>Workaround (if you must stay on v5.0.0)If upgrading isn't possible, you can use tagged variants: template <>
struct glz::meta<VariantStore> {
static constexpr std::string_view tag = "type";
static constexpr auto ids = std::array{
"bool", "int", "float", "string",
"int_array", "float_array", "string_array"
};
};Your JSON would then include an explicit type tag: {"type":"int_array", ...}GCC 12 NoteGCC 12 works with much of Glaze, but recent versions are targetting GCC 13 and up. But, your primary issue is resolved in newer versions of Glaze. |
Beta Was this translation helpful? Give feedback.
Thanks for sharing this detailed report!
The issue is that Glaze v5.0.0 doesn't support auto-deduction for variants with multiple types of the same JSON category. Your variant has three array types:
All three serialize to JSON arrays, and in v5.0.0, Glaze couldn't distinguish between them during deserialization.
This was fixed in v5.6.1 with the addition of parsability-based variant support (#1916). With this feature, Glaze tries each variant alternative in order until one successfully parses.
Solution
Upgrade to Glaze v5.6.1 or later (v7.0.0 is current). Your code should work without any changes:
using VariantStore = std::var…