我嘗試了融合,發現了一些非常奇怪的東西......這裏是代碼...我已經突出顯示有問題的代碼// ############ TROUBLE HERE# #####提升融合奇數
#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;
}
}
}
}
我得到垃圾值或SIGSEGV,如果我使用constRefFieldMap()函數。如果我直接調用boost :: fusion :: zip,它可以很好地工作。下面是輸出...
EUR : 500
isoCode : EUR
rank : 500
我已經看過這個question早些時候...我正在運行到同樣的問題在這裏???
編輯1:
呈現什麼,我試圖做一個例子...
其實...我想寫這樣的代碼。
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;
訪問者,我也可以通過字段名調用修飾符...
我打算寫一個精神解析器解析JSON & XML和創建對象......從我的代碼生成一些幫助。主要思想是避免爲每個對象生成解析代碼,但僅限於那些已使用的對象,並因此減少二進制大小。我現在有1000個物體。
我現在有這個工作。
你會更好過只發佈一個最小的測試案例,恐怕大塊的代碼吸引人走:) :) – 2010-12-01 07:26:16