私はフュージョンを試していて、非常に奇妙なものを見つけました...ここにコードがあります... ###########で問題のあるコードを強調表示しました# #####ブーストフュージョン奇妙
#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;
}
}
}
}
constRefFieldMap()関数を使用すると、ガベージ値またはSIGSEGVが発生します。 boost :: fusion :: zipを直接呼び出すと、それは完全に機能します。ここでは、出力は私が前にこのquestionを見てきました...私はここに同じ問題に実行しています...
EUR : 500
isoCode : EUR
rank : 500
あります?
EDIT 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個のオブジェクトを持っています。
私はこれを今働いています。
あなたは最小限のテストケースを投稿し、より良いオフになっていると思いを与えることはできませんが、私は怖いですコードの大きな塊が人々を遠ざける:) –