2016-10-11 76 views

回答

3

你的慾望d輸出是沒有序列化庫能夠自動執行的,因爲您爲枚舉值提供的名稱僅爲編譯器所知。

通常在這種情況下,您需要提供可以在字符串表示形式和枚舉的數值(例如Enum to String C++)之間進行轉換的代碼,或者使用自動爲您執行此操作的library

讓我們假設你有這個功能。然後您需要編寫專門用於您的枚舉的最小序列化函數對。

這是一個完整的工作示例。你如何選擇從枚舉到字符串取決於你,我使用了兩張地圖,因爲它不需要我真正的努力,但是你可以很容易地將所有這些隱藏在一個宏的後面,以便爲你生成所有必需的代碼:

#include <cereal/archives/json.hpp> 
#include <iostream> 
#include <sstream> 
#include <map> 

enum Color {RED, BLUE, GREEN}; 
enum AnotherEnum {HELLO_WORLD}; 

std::map<Color, std::string> ColorMapForward = {{RED, "RED"}, {BLUE, "BLUE"}, {GREEN, "GREEN"}}; 
std::map<std::string, Color> ColorMapReverse = {{"RED", RED}, {"BLUE", BLUE}, {"GREEN", GREEN}}; 

std::string Color_tostring(Color c) 
{ 
    return ColorMapForward[c]; 
} 

Color Color_fromstring(std::string const & s) 
{ 
    return ColorMapReverse[s]; 
} 

namespace cereal 
{ 
    template <class Archive> inline 
    std::string save_minimal(Archive const &, Color const & t) 
    { 
    return Color_tostring(t); 
    } 

    template <class Archive> inline 
    void load_minimal(Archive const &, Color & t, std::string const & value) 
    { 
    t = Color_fromstring(value); 
    } 
} 

int main() 
{ 
    std::stringstream ss; 

    { 
    cereal::JSONOutputArchive ar(ss); 
    ar(RED); 
    ar(BLUE); 
    ar(GREEN); 
    ar(HELLO_WORLD); // uses standard cereal implementation 
    } 

    std::cout << ss.str() << std::endl; 
    std::stringstream ss2; 

    { 
    cereal::JSONInputArchive ar(ss); 
    cereal::JSONOutputArchive ar2(ss2); 

    Color r, b, g; 
    AnotherEnum a; 

    ar(r, b, g, a); 
    ar2(r, b, g, a); 
    } 

    std::cout << ss2.str() << std::endl; 
} 

給出作爲輸出:

{ 
    "value0": "RED", 
    "value1": "BLUE", 
    "value2": "GREEN", 
    "value3": 0 
} 
{ 
    "value0": "RED", 
    "value1": "BLUE", 
    "value2": "GREEN", 
    "value3": 0 
}