使用BinaryInputArchive/BinaryOutputArchive编译Cereal序列化代码失败
解决Cereal库BinaryArchive编译失败问题
问题根源
你使用了C++20的auto参数语法定义ChatMessage的serialize成员函数:
void serialize(auto& ar) { ar(CEREAL_NVP(sender)); }
这种隐式模板写法虽然符合C++20标准,但Cereal的类型检测机制无法识别它作为合法的序列化模板函数,导致BinaryInputArchive在检查时判定找不到对应的输入序列化方法(JSONArchive因实现细节暂时兼容了这种写法,但这不属于Cereal的标准支持范围)。
修复方案
将serialize函数改为显式模板声明,匹配Cereal要求的标准序列化函数格式:
template<class Archive> void serialize(Archive& ar) { ar(CEREAL_NVP(sender)); }
修改后的完整代码
#include <iostream> #include <sstream> #include <cereal/archives/json.hpp> #include <cereal/archives/binary.hpp> #include <string_view> #include <format> namespace std { template <typename... Args> void println(std::string_view sv, Args&&... args) { std::cout << std::vformat(sv, std::make_format_args(args...)) << std::endl; } } struct ChatMessage { std::string sender; // 修改为显式模板函数 template<class Archive> void serialize(Archive& ar) { ar(CEREAL_NVP(sender)); } }; static std::string getSerializedBinaryString(const ChatMessage & message) noexcept { std::ostringstream oss(std::stringstream::binary); { cereal::BinaryOutputArchive archive(oss); archive(message); } return oss.str(); } static ChatMessage getDeserializedBinaryInst(const std::string & message) noexcept { ChatMessage receivedMessage; { std::istringstream iss(message); cereal::BinaryInputArchive archiveIn(iss); archiveIn(receivedMessage); } return receivedMessage; } int main() { ChatMessage message; message.sender = "Alice"; auto serialize = getSerializedBinaryString(message); std::println("Serialized string is {}", serialize); auto receivedMessage = getDeserializedBinaryInst(serialize); std::println("Sender: {}", receivedMessage.sender); return 0; }
额外说明
Cereal的序列化机制依赖模板特化和类型特性检测,要求序列化函数必须是显式的模板函数,或者提供load/save配对函数。隐式模板(如auto参数)不在Cereal的官方支持范围内,因此会触发类型检测失败的编译错误。
内容的提问来源于stack exchange,提问作者User1234
相关产品推荐
相关产品推荐

