2013-11-22 75 views
2

下面的示例不編譯,抱怨MessagePack,C++:如何使用MSGPACK_DEFINE與C++ 11枚舉類

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類型?

#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++很陌生。這似乎工作

回答

0

的方法之一是包裹在枚舉工會...

union log_level_t { 
    log_level lev; 
    int  levint; 
} 

... 

    log_level_t lev_; 

... 

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

這似乎是一個糟糕的做法,但它的工作原理。

+0

這是使用枚舉類MessagePack的唯一途徑?不那麼優雅! –

0

我找到了另一種解決辦法,也許有點更優雅(好吧,這不是那麼完美):

MSGPACK_DEFINE((int&)lev_, (int&)dom_, msg) 

所以,你可以保留原來的枚舉,而無需創建一個新的聯盟。

反序列化方法應該沒有任何問題。

1

您可以使用MSGPACK_ADD_ENUM()宏。自1.0.0版以來它一直受到支持。我推薦版本1.1.0或更高版本。

請參見: https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_adaptor#enums

我申請MSGPACK_ADD_ENUM()到您的代碼:

#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()); 
}