Доступ к имени поля карты форматирования слияния

Я пытаюсь использовать некоторые из файлов слияния для форматирования, чтобы написать регулярную c struct to file. XML файл кажется хорошим способом захвата данных и обеспечения его совместимости с другими инструментами или редактируемыми вручную. Похоже, что у меня почти есть это, но что-то фундаментальное, кажется, отсутствует. Я использую что-то очень похожее на то, что на странице быстрого запуска boost:: fusion: http://www.boost.org/doc/libs/1_54_0/libs/fusion/doc/html/fusion/quick_start.html. В качестве примечания, которое я подробно рассмотрел здесь и в документации по ускорению, никто, кажется, не обращается к имени поля.

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

Я хочу использовать его следующим образом:

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;

Я знаю, что в данный момент нет ни одного участника, но похоже, что для доступа к названию поля должно получиться! Код, который я отлично работает с x.second, но затем не выполняет то, что мне нужно, чтобы получить имя поля. Как еще я могу это сделать? Спасибо!

Ответ 1

#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);
}