2016-10-11 13 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 
}