LeviLamina
LeviLamina copied to clipboard
[Bug] `mce::UUID` 在反射中被当作 `std::string` 处理
Describe the bug
我希望将 json 数据反射到 std::unordered_set<mce::UUID> 容器内,但是构建失败。
我特化了 UUID 的 deserialize 但是它不工作,反射系统依旧将 mce::UUID 视为 string 处理,但是 mce::UUID 并没有有效的 operator= 可以从 std::string 赋值,导致构建失败。
最小可复现代码:
#include "ll/api/reflection/Deserialization.h"
#include "ll/api/reflection/Reflection.h"
#include "ll/api/reflection/Serialization.h"
#include "mc/platform/UUID.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include <type_traits>
namespace mce {
template <class T, class J>
inline ll::Expected<> deserialize(T& uuid, J const& j) noexcept
requires(std::same_as<T, UUID>)
{
if (j.is_string()) {
if (auto res = UUID::fromString((std::string const&)j); res != UUID::EMPTY()) {
uuid = res;
return {};
}
return ll::makeStringError("invalid uuid");
}
return ll::makeStringError("field must be a string");
}
} // namespace mce
namespace plotx {
void test() {
std::unordered_set<mce::UUID> data;
nlohmann::ordered_json j{};
ll::reflection::deserialize(data, j).value(); // Clangd: In template: no viable overloaded '='
static_assert(!ll::traits::is_string_v<mce::UUID>, "UUID should NOT be string-like"); // false
}
}
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): error C2679: 二元“=”: 没有找到接受“std::string”类型的右操作数的运算符(或没有可接受的转换)
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\mc/platform/UUID.h(57): note: 可能是“mce::UUID &mce::UUID::operator =(mce::UUID &&)”
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): note: “mce::UUID &mce::UUID::operator =(mce::UUID &&)”: 无法将参数 2 从“std::string”转换为“mce::UUID &&”
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): note: 原因如下: 无法从“std::string”转换为“mce::UUID”
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): note: 没有可用于执行该转换的用户定义的转换运算符,或者无法调用该运算符
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\mc/platform/UUID.h(57): note: 或 “mce::UUID &mce::UUID::operator =(const mce::UUID &)”
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): note: “mce::UUID &mce::UUID::operator =(const mce::UUID &)”: 无法将参数 2 从“std::string”转换为“const mce::UUID &”
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): note: 原因如下: 无法从“std::string”转换为“const mce::UUID”
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): note: 没有可用于执行该转换的用户定义的转换运算符,或者无法调用该运算符
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): note: 尝试匹配参数列表“(T, std::string)”时
with
[
T=ll::reflection::deserialize_impl::value_type
]
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(88): note: 模板实例化上下文(最早的实例化上下文)为
D:\Project\PlotX\src\plotx\core\PlotRegistry.cc(41): note: 查看对正在编译的函数 模板 实例化“nonstd::expected_lite::expected<void,ll::Error> ll::reflection::deserialize<std::unordered_set<mce::UUID,std::hash<mce::UUID>,std::equal_to<mce::UUID>,std::allocator<mce::UUID>>,nlohmann::json_abi_v3_11_3::ordered_json&>(T &,J) noexcept”的引用
with
[
T=std::unordered_set<mce::UUID,std::hash<mce::UUID>,std::equal_to<mce::UUID>,std::allocator<mce::UUID>>,
J=nlohmann::json_abi_v3_11_3::ordered_json &
]
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(43): note: 查看对正在编译的函数 模板 实例化“nonstd::expected_lite::expected<void,ll::Error> ll::reflection::deserialize_impl<std::unordered_set<mce::UUID,std::hash<mce::UUID>,std::equal_to<mce::UUID>,std::allocator<mce::UUID>>,nlohmann::json_abi_v3_11_3::ordered_json&>(T &,J,ll::meta::PriorityTag<2>)”的引用
with
[
T=std::unordered_set<mce::UUID,std::hash<mce::UUID>,std::equal_to<mce::UUID>,std::allocator<mce::UUID>>,
J=nlohmann::json_abi_v3_11_3::ordered_json &
]
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(130): note: 查看对正在编译的函数 模板 实例化“nonstd::expected_lite::expected<void,ll::Error> ll::reflection::deserialize<ll::reflection::deserialize_impl::value_type,nlohmann::json_abi_v3_11_3::ordered_json&>(T &,J) noexcept”的引用
with
[
T=ll::reflection::deserialize_impl::value_type,
J=nlohmann::json_abi_v3_11_3::ordered_json &
]
C:\Users\x\AppData\Local\.xmake\packages\l\levilamina\1.4.1\9b537f9b4c15422cbb569116af03d7f3\include\ll/api/reflection/Deserialization.h(43): note: 查看对正在编译的函数 模板 实例化“nonstd::expected_lite::expected<void,ll::Error> ll::reflection::deserialize_impl<ll::reflection::deserialize_impl::value_type,nlohmann::json_abi_v3_11_3::ordered_json&>(T &,J,ll::meta::PriorityTag<4>)”的引用
with
[
T=ll::reflection::deserialize_impl::value_type,
J=nlohmann::json_abi_v3_11_3::ordered_json &
]
ninja: build stopped: subcommand failed.
To Reproduce
如上
Expected behavior
正常反射
Screenshots
No response
Platform
win10
Version
1.4.1
Additional context
No response