我想生成包含50个以上元素的boost fusion
类型序列。 boost/fusion/container/vector/vector50.hpp的内容似乎暗示可能会以某种方式使用宏BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
来影响此限制。
我创建了以下简单程序,它将int
推送到boost::fusion::vector
类型指定的次数,然后将结果转换为向量(触发错误)。< / p>
#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 ......
答案 0 :(得分:2)
这是一个两步法,首先在编译标志中定义: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()
}}
嗯..我不认为除了修补之外还有其他方法。上面的代码..
EDIT2:嗯,如果有意图破解,显然有一种方法(无需修改提升),它确实附带了一个巨大的免责声明 - 正确测试,它编译,你可以访问超过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测试)
答案 1 :(得分:0)
在我看来,预处理文件只是编译时优化。
在这种情况下,您可能希望(?)大胆地前往以往没有人去过的地方:
编辑该文件中的限制:
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.hpp
,vector70.hpp
...并将其包含在适当的位置
我没有测试过这个,但值得一试
答案 2 :(得分:0)
似乎没有可能在没有黑客入侵或使用boost wave
预处理器的情况下扩展此限制,对我来说这两者都不是可行的选项。这里唯一真正的解决方案是使std::tuple
使用mpl
功能,并使用它而不是fusion
容器。这个答案显示了如何做到这一点: