2014-10-09 3 views
1

Кто-нибудь когда-либо пытался создать набор макросов, которые автоматически создают класс с произвольным набором переменных-членов, а затем добавляют поддержку для его сериализации?генерация класса C++ с произвольными переменными-членами с использованием макросов

Например, я хотел бы, чтобы иметь возможность написать файл, содержащий код вроде следующего:

GENERATED_CLASS(MyClass) 
    GENERATED_CLASS_MEMBER(int, foo); 
    GENERATED_CLASS_MEMBER(std::string, bar); 
END_GENERATED_CLASS(); 

GENERATED_CLASS(MySecondClass) 
    GENERAGED_CLASS_MEMBER(double, baz); 
END_GENERATED_CLASS(); 

GENERATED_DERIVED_CLASS(MyClass, MyThirdClass) 
    GENERATED_CLASS_MEMBER(bool, bat); 
END_GENERATED_CLASS(); 

, что эффективно приводит к

class MyClass 
{ 
public: 
    MyClass() {}; 
    ~MyClass() {}; 

    void set_foo(int value) { foo = value; } 
    void set_bar(std::string value) { bar = value; } 
    int get_foo() { return foo; } 
    std::string get_bar() { return bar; } 

private: 
    int foo; 
    std::string bar; 
}; 

std::ostream& operator<<(std::ostream& os, const MyClass& obj) 
{ 
    /* automatically generated code to serialize the obj, 
    * i.e. foo and bar */ 
    return os; 
} 

std::istream& operator>>(std::istream& os, MyClass& obj) 
{ 
    /* automatically generated code to deserialize the obj, 
    * i.e. foo and bar */ 
    return os; 
} 

class MySecondClass 
{ 
public: 
    MySecondClass() {}; 
    ~MySecondClass() {}; 

    void set_baz(double value) { baz = value; } 
    double get_baz() { return baz; } 

private: 
    double baz; 
}; 

std::ostream& operator<<(std::ostream& os, const MySecondClass& obj) 
{ 
    /* automatically generated code to serialize the obj, 
    * i.e. baz */ 
    return os; 
} 

std::istream& operator>>(std::istream& os, MySecondClass& obj) 
{ 
    /* automatically generated code to deserialize the obj, 
    * i.e. baz */ 
    return os; 
} 

class MyThirdClass : public MyClass 
{ 
public: 
    MyThirdClass() {}; 
    ~MyThirdClass() {}; 

    void set_bat(bool value) { bat = value; } 
    bool get_bat() { return bat; } 

private: 
    bool bat; 
}; 

std::ostream& operator<<(std::ostream& os, const MyThirdClass& obj) 
{ 
    /* automatically generated code to serialize the obj, 
    * i.e. call the << operator for the baseclass, 
    * then serialize bat */ 
    return os; 
} 

std::istream& operator>>(std::istream& os, MyThirdClass& obj) 
{ 
    /* automatically generated code to deserialize the obj, 
    * i.e. call the << operator for the baseclass, 
    * then serialize bat */ 
    return os; 
} 

генерируется из прекомпилятором.

Я просто не уверен в том, как это сделать. Я не против использования вариативных шаблонов и вариативных макросов, если кто-то может мне рассказать, но я бы очень хотел, чтобы избежать повышения, написания моего собственного препроцессора, добавления любой настраиваемой магии makefile и т. Д., Чтобы выполнить это - чистый C++ если возможно.

Любые предложения?

+1

Отладочный код, подобный этому, был бы кошмаром. –

+0

Возможно, но g ++ -E, безусловно, был бы вашим другом. – awfulfalafel

ответ

1

Одним из решений, которое выполняет практически то, что вы хотите сделать, является google protocol buffers. Он позволяет определять структуры в определенном формате (IDL), а затем создает код C++ (классы, сериализация и т. Д.).

+0

Да, но protobufs использует отдельный генератор кода. – dom0

+0

Правда, я полагаю, вы, вероятно, предпочтете сделать это сами :). Я не знаю никаких решений, созданных исключительно на C++. – lisu