3

은 내가 MPL 순서를 보면객체 직렬화를위한 코드를 생성하기 위해 MPL을 향상 시키시겠습니까? 어떻게 것

class Object 
{ 
    string a; 
    int b; 
    long c; 
    char d; 
}; 

에 대한 직렬화/역 직렬화 코드를 생성 할,하지만 난 알아낼 수 없습니다, 오브젝트를 식별뿐만 아니라 다시 검색 할 수 있어야합니다 그 회원의 이름을 얻으려면 내가 그것을 알아야 하느냐?

코드는, 행할,

난 단지 개체의 레이아웃을 해당하는 MPL 순서를 정의하는 사용자가 위의 코드를 생성 할
void SerializeObject(ostream os) 
{ 
    serialize(object.a, os); 
    serialize(object.b, os); 

    //serialize(object.member, os); 
} 

과 같아야합니다 당신은 내게 몇 가지 힌트를 줄 수 있습니까?

내 목표는 다음과 같습니다

사용자는 상기 목적을 위해 mpl::vector<String, int, long, char>을 정의하고 내 metaprogram는 필요한 코딩 된 생성 할 수 있습니다.

+0

심각한 해킹없이 회원의 이름을 얻을 수 있다고 생각하지 않습니다. 예를 들어 두 개의 int가 있으면 어떻게 될지 고려하십시오. boost :: mpl은 어느 int가 어떤 것을 알고 있습니까? –

+0

@Boaz, 나는 둘 다'int'를 얻은만큼 내가 상관하지 않는다. –

답변

2

템플릿의 멤버 이름을 유추하는 방법이 없습니다.

template<typename ObjT, typename MemberT, MemberT ObjT::*Ptr> 
struct member{}; 

mpl::vector 
< 
    member<Object, string, &Object::a>, 
    member<Object, int, &Object::b>, 
    member<Object, long, &Object::c>, 
    member<Object, char, &Object::d> 
>; 

또 다른 옵션은 member_vec로 병합 member에 대한 operator>>을 정의 member을 생성하기 위해 함수를 만드는 것입니다, 그리고로 병합 member_vec에 대한 operator>> : 당신은 다음과 같이 명시 적으로 모든 것을 지정해야합니다 더 큰 것 member_vec. 당신은 단지 유형을 사용하고 있기 때문에, 컴파일러는 실제 함수가 암시 적 템플릿 인수를 사용할 수 있습니다

함수를 호출 최적화 할 수 있으므로 시리얼 정의 할 약간 적은 코드를 취할 수 있습니다 :

auto serializer = 
     mem(&Object::a) >> 
     mem(&Object::b) >> 
     mem(&Object::c) >> 
     mem(&Object::d); 

I을 두 기술을 모두 사용하여 직접 직렬 프로그램을 만들었습니다. 두 번째 것은 내가 가장 행복했던 것입니다.

10

boost::fusion을 고려하고 BOOST_FUSION_ADAPT_STRUCT() 매크로를 사용하여 구조를 융합 시퀀스 (임의 액세스)로 승격 시키십시오. 위의 구조를 정의하고 나면, 당신은 지금이 추진되고 있다고

BOOST_FUSION_ADAPT_STRUCT(
    Object, 
    (std::string, a) 
    (int, b) 
    (long, c) 
    (char, d) 
) 

과 같은 작업을 수행 할 수 있습니다, 당신은 단순히 멤버를 통해 반복하는 for_each을 사용할 수 있습니다, 뭔가 같은 :

template<typename archive> 
struct serializer { 
    serializer(archive& ar):ar(ar) {} 

    template<typename T> 
    void operator()(const T& o) const { 
     ar & o; // assuming binary for example... 
    } 
    archive& ar; 
}; 

template<typename archive, typename sequence> 
void serialize(archive& ar, sequence const& v) { 
    boost::fusion::for_each(v, serializer<archive>(ar)); 
} 

으로 당신은 멤버 이름을 나타내는 mpl::string을 사용할 수 있습니다

Object foo; // instance to serialize 
serialize(<archive>, foo); 
0

:로 사용, 그것은 간단해야한다. 내 응용 프로그램에서는 다음과 같은 코드를 생성합니다.

typedef mpl::string < 'n', 'a', 'm', 'e' > name; 

mpl::c_str <name>::value을 사용하면 문자열 표현을 얻을 수 있습니다. 즉 "이름".

이러한 멤버 이름의 시퀀스, 멤버 포인터의 다른 시퀀스를 저장 한 다음 boost :: fusion 쿼리 알고리즘 중 하나를 사용하여 주어진 멤버 이름에 대한 멤버 포인터를 찾습니다.

관심이 있으시면 코드를 게시하겠습니다. 현재 내 집 PC에 있기 때문에 액세스 할 수 없습니다.

관련 문제