Ich versuche Fusion und fand etwas sehr merkwürdig ... Hier ist der Code ... Ich habe den problematischen Code mit hervorgehoben // ############ HIER ### #####Boost Fusion Kuriosität
#include <tr1/cstdint>
#include <tr1/functional>
#include <string>
#include <iostream>
// #define FUSION_MAX_VECTOR_SIZE 64
#define BOOST_MPL_LIMIT_STRING_SIZE 128
#include <boost/type_traits.hpp>
#include <boost/mpl/string.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/tuple.hpp>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/container/generation.hpp>
#include <boost/fusion/container/generation/vector_tie.hpp>
typedef std::tr1::int32_t int32;
typedef std::tr1::int64_t int64;
template < class type_const_ref >
struct remove_const_reference
{
typedef typename boost::remove_reference <type_const_ref>::type type_const;
typedef typename boost::remove_const <type_const>::type type;
};
template < class T >
class MetaClass;
namespace fusion = boost::fusion;
template < class T >
struct ConstRefFieldMap
{
typedef typename MetaClass <T>::FieldNames FieldNames;
typedef typename MetaClass <T>::ConstRefFields ConstRefFields;
typedef typename boost::fusion::result_of::zip < FieldNames const, ConstRefFields const >::type type;
};
template < class T >
static typename MetaClass <T>::FieldNames fieldNames()
{
return typename MetaClass <T>::FieldNames();
}
template < class T >
static typename MetaClass <T>::ConstRefFields constRefFields(T const &obj)
{
return MetaClass <T>::constRefFields(obj);
}
template < class T >
static typename ConstRefFieldMap <T>::type const constRefFieldMap(T const &obj)
{
return boost::fusion::zip(fieldNames <T>(), constRefFields(obj));
}
class Currency
{
private:
typedef MetaClass <Currency> Meta;
friend class MetaClass <Currency>;
private:
std::string m_isoCode;
int32 m_rank;
public:
Currency(std::string const &isoCode, int32 const rank)
: m_isoCode(isoCode)
, m_rank(rank)
{
}
std::string const& getIsoCode() const
{
return m_isoCode;
}
int32 const getRank() const
{
return m_rank;
}
private:
void setIsoCode(std::string const &isoCode)
{
m_isoCode = isoCode;
}
public:
void setRank(int32 rank)
{
m_rank = rank;
}
};
template <>
class MetaClass <Currency>
{
public:
typedef Currency data_type;
public:
typedef std::string IsoCodeType;
typedef int32 RankType;
typedef boost::fusion::vector <
boost::mpl::string < 'i', 's', 'o', 'C', 'o', 'd', 'e' >
, boost::mpl::string < 'r', 'a', 'n', 'k' >
> FieldNames;
typedef boost::fusion::vector <
IsoCodeType &
, RankType &
> MutableRefFields;
typedef boost::fusion::vector <
IsoCodeType const &
, RankType const &
> ConstRefFields;
static MutableRefFields mutableRefFields(Currency &obj)
{
return MutableRefFields(obj.m_isoCode, obj.m_rank);
}
static ConstRefFields constRefFields(Currency const &obj)
{
return ConstRefFields(obj.m_isoCode, obj.m_rank);
}
};
template < class T, class U >
static typename ConstRefFieldMap <T>::type const constRefFieldMapTest(T const &obj, U const &u)
{
return boost::fusion::zip(fieldNames <T>(), u);
}
int main()
{
Currency const EUR("EUR", 500);
using boost::fusion::any;
{
std::cout << boost::fusion::at_c <0>(constRefFields(EUR)) << " : " << boost::fusion::at_c <1>(constRefFields(EUR)) << std::endl;
ConstRefFieldMap <Currency>::type const &fm = boost::fusion::zip(fieldNames <Currency>(), constRefFields(EUR));
// ############ TROUBLE HERE ######
// ConstRefFieldMap <Currency>::type const &fm = constRefFieldMap(EUR);
// ############ TROUBLE HERE ######
{
{
typedef boost::fusion::result_of::at_c < ConstRefFieldMap <Currency>::type, 0 >::type field_value_type;
field_value_type const v = boost::fusion::at_c <0>(fm);
typedef boost::fusion::result_of::at_c < field_value_type, 0 >::type field_name_type;
field_name_type const n = boost::fusion::at_c <0>(v);
typedef boost::fusion::result_of::at_c < field_value_type, 1 >::type field_data_type;
field_data_type const d = boost::fusion::at_c <1>(v);
std::cout << boost::mpl::c_str < remove_const_reference <field_name_type>::type >::value << " : " << d << std::endl;
}
{
typedef boost::fusion::result_of::at_c < ConstRefFieldMap <Currency>::type, 1 >::type field_value_type;
field_value_type const v = boost::fusion::at_c <1>(fm);
typedef boost::fusion::result_of::at_c < field_value_type, 0 >::type field_name_type;
field_name_type const n = boost::fusion::at_c <0>(v);
typedef boost::fusion::result_of::at_c < field_value_type, 1 >::type field_data_type;
field_data_type const d = boost::fusion::at_c <1>(v);
std::cout << boost::mpl::c_str < remove_const_reference <field_name_type>::type >::value << " : " << d << std::endl;
}
}
}
}
ich Müll Werte oder SIGSEGV, wenn ich die constRefFieldMap() Funktion verwenden. Wenn ich boost :: fusion :: zip direkt anrufe, funktioniert das perfekt. Hier ist die Ausgabe ...
EUR : 500
isoCode : EUR
rank : 500
Ich habe in diesem question sah früher ... bin ich in das gleiche Problem laufen hier ???
EDIT 1:
Presenting ein Beispiel von dem, was ich zu tun versuchen ...
Eigentlich ... Ich versuche, Code wie diesen zu schreiben.
MetaObject < Currency const > EUR_META(make_meta_object(EUR));
std::cout << get_field <std::string>("isoCode", EUR_META.constRefFieldMap()) << std::endl;
MetaObject <Currency> GBP_META(make_meta_object(GBP));
MutableRefFieldMap <Currency>::type const &fm = GBP_META.mutableRefFieldMap();
std::cout << set_field("rank", fm, 497) << std::endl;
Zugriffs- und Modifikatoren, die ich von Feldnamen aufrufen können ...
Ich plane einen Geist Parser schreiben JSON & XML zu analysieren und Objekte erstellen ... mit etwas Hilfe von meinem Code-Generatoren. Die Grundidee besteht darin, zu vermeiden, dass der Parsing-Code für jedes Objekt erzeugt wird, sondern nur für die Objekte, die verwendet werden und somit die Binärgröße reduzieren. Ich habe jetzt 1000 Objekte.
Ich habe das jetzt funktioniert.
Sie besser dran, nur einen minimalen Testfalls Entsendung gewesen sein würden, fürchte mich, große Teile des Codes ziehen Leute weg :) –