Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 助推聚变奇异性_C++_Metaprogramming_Boost Fusion - Fatal编程技术网

C++ 助推聚变奇异性

C++ 助推聚变奇异性,c++,metaprogramming,boost-fusion,C++,Metaprogramming,Boost Fusion,我正在尝试融合,发现了一些非常奇怪的东西。。。这是代码。。。我在这里用//TROUBLE突出显示了有问题的代码 #include <tr1/cstdint> #include <tr1/functional> #include <string> #include <iostream> // #define FUSION_MAX_VECTOR_SIZE 64 #define BOOST_MPL_LIMIT_STRING_SIZE 128 #i

我正在尝试融合,发现了一些非常奇怪的东西。。。这是代码。。。我在这里用//TROUBLE突出显示了有问题的代码

#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;
            }
        }
    }
}
我之前看过这个。。。我在这里遇到了同样的问题吗

编辑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;
我可以通过字段名调用的访问器和修饰符

我计划编写一个spirit解析器来解析JSON和XML并创建对象。。。在我的代码生成器的帮助下。其主要思想是避免为每个对象生成解析代码,而仅为使用的对象生成解析代码,从而减少二进制大小。我现在有1000件物品


我现在已经开始工作了。

不幸的是,这个问题没有引起更多的注意,但我想大量的代码并没有起到多大的作用,而且模板元编程并不那么流行

无论如何,你是对的,这是一个类似的问题

问题是fusion中的视图不复制参数,它们只保留对参数的引用。这允许您通过中间参数修改原始参数

问题是C++中有权将临时绑定到const引用,并且将临时生存期扩展到引用的引用。然而,这种行为是不可传递的,这已经造成了大量的麻烦。Clang将尝试诊断这些情况,不幸的是第一个补丁失败:p

因此,您的问题只存在于一行:

return boost::fusion::zip(fieldNames < T >(), constRefFields(obj));
fieldNames创建一个临时变量,该变量绑定到常量引用,它的生存期将延长到表达式的结尾:; 当您返回视图时,临时生存期已经过期,您将保留一个悬空引用 快速修复:使FieldName有一个局部静态变量并返回对此变量的引用,这将修复生存期问题


但我仍然不明白您在尝试什么,因此我无法给出更明智的建议:

您最好只发布一个最小的测试用例,我担心大块的代码会吸引人们离开:+1,因为我想大块的代码并没有多大帮助——而且对挖掘它也没有多大帮助。@zrb:我知道这就是你正在研究的东西,但问题是,可能帮助你的人可能会拒绝,因为通读所有这些并理解你试图实现的目标需要时间。如果发布一个最小的测试用例,对我们来说会更容易,因此您会得到更多的答案:这是复制问题的最小代码量。无论如何,一定要测试一下我提到的快速修复方法,我认为它应该能解决你的问题。谢谢。这个问题实际上与Constructefields有关。我现在已经解决了这个问题。
return boost::fusion::zip(fieldNames < T >(), constRefFields(obj));