你好,我想创建一个序列化类来序列化我的变量设置到文件或缓冲区。我一直做得很好,直到我开始在我的类中实现std::variant<T...>。据我所知。我不能在运行时获得变量类型。它需要在编译时完成。但我想存储在文件中。所以这里是我的代码。
class Serialization
{
private:
std::vector<char> buffer;
public:
inline std::size_t size()const{return buffer.size();};
Serialization()=default;
template<typename T>
Serialization& operator<<(const T& val){
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
const auto size = buffer.size();
buffer.resize(buffer.size()+sizeof(T));
std::memcpy(buffer.data() + size, static_cast<const void*>(&val), sizeof(T));
return *this;
}
template<typename T>
Serialization& operator>>(T& val){
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
std::memcpy(&val, buffer.data(), sizeof(T));
buffer.erase(buffer.begin(), buffer.begin() + sizeof(T));
return *this;
}
template<typename T>
Serialization& operator<<(const std::vector<T>& val) {
const auto size = val.size();
*this << size;
for(const auto& elem : val){
*this << elem;
}
return *this;
}
template<typename T>
Serialization& operator>>(std::vector<T>& val) {
size_t size;
*this >> size;
val.resize(size);
for(auto& elem : val){
*this >> elem;
}
return *this;
}
template< class... Types >
Serialization& operator<<(const std::variant<Types...>& val) {
const std::size_t index = val.index();
*this << index;
std::visit([&](const auto& value){
*this << value;
}, val);
return *this;
}
template< class... Types >
Serialization& operator>>(std::variant<Types...>& val) {
std::size_t index;
*this >> index;
if (index >= sizeof...(Types)) {
throw std::out_of_range("Variant index out of range");
}
using value_type = std::variant_alternative_t<index, std::variant<Types...>>;
//auto value = expand_type<Types...>(index);
value_type value;
*this >> value;
val.emplace<index>(std::move(value));
return *this;
}
//I also try this one
template <typename... Ts>
[[nodiscard]] std::variant<Ts...>
expand_type(std::size_t i)
{
assert(i < sizeof...(Ts));
static constexpr std::variant<Ts...> table[] = { Ts{ }... };
return table[i];
}
friend std::ostream & operator << (std::ostream &out, const Serialization &s);
friend std::istream & operator >> (std::istream &in, Serialization &s);
~Serialization()=default;
};
template<>
Serialization& Serialization::operator<<(const std::string& val){
const auto size = val.size();
*this << size;
buffer.insert(buffer.end(), val.begin(), val.end());
return *this;
}
template<>
Serialization& Serialization::operator>>(std::string& val) {
size_t size;
*this >> size;
val.resize(size);
std::memcpy(&val[0], buffer.data(), size);
buffer.erase(buffer.begin(), buffer.begin() +size);
return *this;
}
std::ostream & operator << (std::ostream &out, const Serialization &s){
out.write(s.buffer.data(),s.buffer.size());
return out;
}
std::istream & operator >> (std::istream &in, Serialization &s){
in.seekg(0, std::ios::end);
s.buffer.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(s.buffer.data(), s.buffer.size());
return in;
}
我查看论坛、博客和文档,也问过ChatGPT,但找不到实现的方法。
1条答案
按热度按时间azpvetkf1#
使用函数指针数组,您可以执行以下操作:
不幸的是,gcc似乎不支持这一点,您必须使用常规函数/方法而不是lambda