如何将聚变容器的大小限制扩展到50以上

How do I extend the fusion container size limits beyond 50?

本文关键字:扩展到 以上      更新时间:2023-10-16

我想生成包含50个以上元素的boost fusion类型序列。boost/fusion/container/vector/vector50.hpp的内容似乎表明,宏BOOST_FUSION_DONT_USE_PREPROCESSED_FILES可能会以某种方式影响这一极限。

我创建了以下简单程序,它将int推回到boost::fusion::vector类型上指定次数,然后将结果转换为向量(这会触发错误)。

#include <boost/fusion/container.hpp>                                              
#include <boost/fusion/algorithm.hpp>                                              
#include <type_traits>                                                             
template <typename Sequence, int N>                                                
struct PushBack                                                                    
{                                                                                  
    using type = typename PushBack<typename boost::fusion::result_of::push_back<Sequence, int>::type, N-1>::type;
};                                                                                 
template <typename Sequence>                                                       
struct PushBack<Sequence, 0>                                                       
{                                                                                  
    using type = Sequence;                                                         
};                                                                                 
int main()                                                                         
{                                                                                  
    using NullVector = boost::fusion::vector<>;                                    
    using Sequence = boost::fusion::result_of::as_vector<typename PushBack<NullVector, 20>::type>::type; // this line triggers the error
    Sequence s;                                                                    
    return 0;                                                                      
}                          

当我用-D BOOST_FUSION_DONT_USE_PREPROCESSED_FILES -D FUSION_MAX_VECTOR_SIZE=100运行这个程序时,我会收到大量错误,大致如下所示:

/boost/fusion/container/generation/make_vector.hpp:105:25:错误:"vector51"未命名类型…/boost/fusion/container/generation/make_vector.hpp:105:25:错误:"vector52"未命名类型…/boost/fusion/container/generation/make_vector.hpp:105:25:错误:"vector…"没有命名类型

很明显我做得不对。如何将此限制延长到50以上?我需要至少150…

这是一种分两步的方法,首先在编译标志中定义:BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS,然后用-DBOOST_MPL_LIMIT_VECTOR_SIZE=50 -DFUSION_MAX_VECTOR_SIZE=50(最接近的10)设置所需的大小

编辑:

你确实运气不好,在标题中,即使你不使用预处理的标题,看起来也被这段代码限制在50以内:

#if (FUSION_MAX_VECTOR_SIZE > 40)
#include <boost/fusion/container/vector/vector50.hpp>
#endif

然后做了一件非常愚蠢的事情:

#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/vector_n.hpp>
#define BOOST_PP_ITERATION_LIMITS (41, 50)
#include BOOST_PP_ITERATE()
}}

嗯。。我认为除了"修补"上面的代码之外,没有其他方法了。。

第二版:好吧,如果有黑客的意愿,显然有一种方法(不必修改boost),它确实有一个巨大的免责声明-正确测试,它编译,你可以访问50以上的元素,这就是我将提供的所有保修。。。

#include <iostream>
#define BOOST_MPL_LIMIT_VECTOR_SIZE 50
#define FUSION_MAX_VECTOR_SIZE 60
// This sets us up with mpl vector up to 50
#include <boost/mpl/vector.hpp>
// This adds the missing chunk - you should be able to expand this up to template depth
// This sets up the sequence of vectors (vector1 : T + vector0 etc.
#include <boost/fusion/sequence/intrinsic/begin.hpp>
namespace boost { namespace mpl {
#   define BOOST_PP_ITERATION_PARAMS_1 
    (3,(51, 60, <boost/mpl/vector/aux_/numbered.hpp>))
#   include BOOST_PP_ITERATE()
}}
// This sets up the specializations
#define AUX778076_SEQUENCE_BASE_NAME vector
#   define AUX778076_SEQUENCE_LIMIT BOOST_MPL_LIMIT_VECTOR_SIZE
#   define AUX778076_SEQUENCE_CONVERT_CN_TO(z,n,TARGET) TARGET(BOOST_PP_CAT(C,n))
#   include <boost/mpl/aux_/sequence_wrapper.hpp>
// Include everuthing up to vector50
#define BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
#include <boost/fusion/container/vector/vector50.hpp>
// Add the missing range
namespace boost
{
namespace fusion
{
struct vector_tag;
#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/vector_n.hpp>
#define BOOST_PP_ITERATION_LIMITS (51, 60)
#include BOOST_PP_ITERATE()
}
}
// Declare the vector class using the FUSION_MAX_VECTOR_SIZE, as the types themselves have been declared above, all is
// good in the world of fusion
#include <boost/fusion/container/vector/vector.hpp>

// Test access
#include <boost/fusion/sequence/intrinsic/at_c.hpp>

int main()
{
  using Sequence = typename boost::fusion::vector<
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    int,
    double,
    std::string,
    std::string
 >;
 Sequence s;
 std::cout << boost::fusion::at_c<51>(s) << std::endl;
}

基本上,我在上面所做的只是填充缺失的比特(对于大于50的计数),但根据需要实例化mpl和fusion的比特。上面的操作序列非常严格,如果有人能进一步提取它,请更新。。。

(注:使用gcc-4.8.2、boost-1.55、c++11进行测试)

在我看来,预处理的文件只是编译时的优化。

在这种情况下,你可能想(?)大胆地去以前没有人去过的地方,或者:

  • 编辑该文件中的限制:

    namespace boost { namespace fusion
    {
        struct vector_tag;
        struct fusion_sequence_tag;
        struct random_access_traversal_tag;
    // expand vector41 to vector50
    #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/vector_n.hpp>
    #define BOOST_PP_ITERATION_LIMITS (41, 100)
    #include BOOST_PP_ITERATE()
    }}
    
  • 添加更多类似的标题,例如vector60.hppvector70.hpp。。。并将其包含在的适当位置

我还没有测试过,但值得一试

如果不侵入boost或使用boost wave预处理器,似乎不可能扩展此限制,这对我来说都不是可行的选择。这里唯一真正的解决方案是调整std::tuple以使用mpl功能,并使用它来代替fusion容器。这个答案正好说明了如何做到这一点:

https://stackoverflow.com/a/15865204/1613983