2013-07-24 8 views
11

나는 파일에 일반 c struct를 작성하기 위해 boost fusion 자료를 사용하려고 시도 해왔다. XML 파일은 데이터를 캡처하여 다른 도구와 호환되거나 손으로 편집 할 수있는 좋은 방법입니다. 거의 가지고있는 것 같지만 근본적인 것이 빠져있는 것처럼 보입니다. 저는 boost :: fusion quick start 페이지의 내용과 꽤 비슷한 것을 사용하고 있습니다 : http://www.boost.org/doc/libs/1_54_0/libs/fusion/doc/html/fusion/quick_start.html. 참고로 나는 철저하게 여기와 부스트의 문서를 보았지만 아무도 필드 이름에 액세스하는 것 같지 않습니다.부스트 퓨전 맵 필드 이름에 액세스

BOOST_FUSION_ADAPT_STRUCT(
    myStructType, 
    (double, val1) 
    (double, val2) 
    (char, letter) 
    (int, number) 
    )  
myStructType saveMe = { 3.4, 5.6, 'g', 9}; 
for_each(saveMe, print_xml()); 

다른 시간 나는대로 다음과 구조체를 정의하지만, 여전히 운 : 내가 아는

namespace fields{ 
    struct val1; 
    struct val2; 
    struct letter; 
    struct number; 
} 

typedef fusion::map< 
    fusion::pair<fields::val1, double>, 
    fusion::pair<fields::val2, double>, 
    fusion::pair<fields::letter, char>, 
    fusion::pair<fields::number, int> > myStructType; 

어떤 멤버가 처음이없는 다음 없기 때문에

struct print_xml 
{ 
    template <typename T> 
    void operator()(T const& x) const 
    { 
     std::cout 
      << '<' << x.first << '>' 
      << x 
      << "</" << x.first << '>' 
      ; 
    } 
}; 

나는 그것을 사용하려면 , 실제로 필드 이름에 액세스해야하는 것처럼 보입니다! 내가 가지고있는 코드는 x.second와 잘 동작하지만 필드 이름을 얻는 것이 필요한 것은 아니다. 다른 방법으로이 작업을 수행 할 수 있습니까? 감사합니다.

답변

14
#include <iostream> 
#include <string> 

#include <boost/mpl/range_c.hpp> 
#include <boost/fusion/include/for_each.hpp> 
#include <boost/fusion/include/zip.hpp> 
#include <boost/fusion/include/at_c.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/fusion/include/mpl.hpp> 

namespace fusion=boost::fusion; 
namespace mpl=boost::mpl; 

struct myStructType 
{ 
    double val1; 
    double val2; 
    char letter; 
    int number; 
}; 

BOOST_FUSION_ADAPT_STRUCT(
    myStructType, 
    (double, val1) 
    (double, val2) 
    (char, letter) 
    (int, number) 
) 



template <typename Sequence> 
struct XmlFieldNamePrinter 
{ 
    XmlFieldNamePrinter(const Sequence& seq):seq_(seq){} 
    const Sequence& seq_; 
    template <typename Index> 
    void operator() (Index idx) const 
    { 
     //use `Index::value` instead of `idx` if your compiler fails with it 
     std::string field_name = fusion::extension::struct_member_name<Sequence,idx>::call(); 

     std::cout 
      << '<' << field_name << '>' 
      << fusion::at<Index>(seq_) 
      << "</" << field_name << '>' 
      ; 
    } 
}; 
template<typename Sequence> 
void printXml(Sequence const& v) 
{ 
    typedef mpl::range_c<unsigned, 0, fusion::result_of::size<Sequence>::value > Indices; 
    fusion::for_each(Indices(), XmlFieldNamePrinter<Sequence>(v)); 
} 

int main() 
{ 
    myStructType saveMe = { 3.4, 5.6, 'g', 9}; 
    printXml(saveMe); 
} 
+1

놀라운 점 :/나는이 존재하지 않았다. – sehe