首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MessagePack,c++:如何在c++11枚举类中使用MSGPACK_DEFINE

MessagePack,c++:如何在c++11枚举类中使用MSGPACK_DEFINE
EN

Stack Overflow用户
提问于 2013-11-22 21:30:44
回答 3查看 5K关注 0票数 4

以下示例未编译,抱怨

代码语言:javascript
运行
复制
In file included from /usr/include/msgpack.hpp:18:
/usr/include/msgpack/object.hpp:211:3: error: member reference base type 'logd::log_level' is not a structure or union

以及另一个枚举类的相应错误。我的问题是,如何使用msgpack的c++ api来序列化具有c++11 enum class类型的成员的类?

代码语言:javascript
运行
复制
#ifndef LOG_MSG_HPP_
#define LOG_MSG_HPP_

#include <stdlib.h>
#include <msgpack.hpp>

/** @namespace logd */
namespace logd {

enum class log_level { SILENT,... DEBUG };

enum class log_domain { AI, ...  MISC };

class log_msg {
    public:
        log_msg(log_level lev, log_domain dom, std::string msg);
        log_level level();
        log_domain domain();
        std::string message();
        ~log_msg();
        MSGPACK_DEFINE(lev_, dom_, msg_);

    private:
        log_msg();
        log_level   lev_ {log_level::DEBUG};
        log_domain  dom_ {log_domain::MISC};
        std::string msg_ {"No message given."};
};
} /* namespace logd */
#endif /* LOG_MSG_HPP_ */

注意:由于枚举是我的,我可以很高兴地修改它们,使msgpack快乐。不幸的是,我在他们的文档或Google的前几页中找不到关于这个主题的参考资料。我也无法从读取它们的头/源中确定该做什么,因为我对c++相当陌生。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-23 01:33:15

一种似乎可行的方法就是把气包在一起.

代码语言:javascript
运行
复制
union log_level_t {
    log_level lev;
    int       levint;
}

...

    log_level_t lev_;

...

MSGPACK_DEFINE(lev_.levint, dom_.domint, msg);

这似乎是一种拙劣的方法,但有效。

票数 0
EN

Stack Overflow用户

发布于 2015-04-14 02:49:33

您可以使用MSGPACK_ADD_ENUM()宏。从1.0.0版本开始就支持它。我推荐版本1.1.0或更高版本。

请参阅:adaptor#enums

我将MSGPACK_ADD_ENUM()应用于您的代码:

代码语言:javascript
运行
复制
#ifndef LOG_MSG_HPP_
#define LOG_MSG_HPP_

#include <stdlib.h>
#include <msgpack.hpp>

/** @namespace logd */
namespace logd {

enum class log_level { SILENT,DEBUG };

enum class log_domain { AI, MISC };

class log_msg {
    public:
        log_msg(log_level lev, log_domain dom, std::string msg):lev_(lev), dom_(dom), msg_(msg) {}
        log_level level() { return lev_;}
        log_domain domain() { return dom_;}
        std::string message() { return msg_; }
        ~log_msg() {}
        MSGPACK_DEFINE(lev_, dom_, msg_);
        log_msg() = default;

    private:
        log_level   lev_ {log_level::DEBUG};
        log_domain  dom_ {log_domain::MISC};
        std::string msg_ {"No message given."};
};
} /* namespace logd */

MSGPACK_ADD_ENUM(logd::log_level);
MSGPACK_ADD_ENUM(logd::log_domain);


#endif /* LOG_MSG_HPP_ */

#include <sstream>
#include <cassert>

int main() {
    logd::log_msg lm { logd::log_level::SILENT, logd::log_domain::AI, "hello" };
    std::stringstream ss;
    msgpack::pack(ss, lm);

    msgpack::object obj = msgpack::unpack(ss.str().data(), ss.str().size()).get();
    logd::log_msg lm2 = obj.as<logd::log_msg>();
    assert(lm.level() == lm2.level());
    assert(lm.domain() == lm2.domain());
    assert(lm.message() == lm2.message());
}
票数 6
EN

Stack Overflow用户

发布于 2015-04-03 16:05:44

我找到了另一个解决方案,也许更优雅一些(好吧,它并不完美):

代码语言:javascript
运行
复制
MSGPACK_DEFINE((int&)lev_, (int&)dom_, msg)

所以你可以保留你原来的枚举而不创建一个新的联盟。

反序列化方法应该没有任何问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20154853

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档