我想生成包含超过 50 个元素的 boost fusion
类型序列。 boost/fusion/container/vector/vector50.hpp的内容似乎暗示可以使用宏 BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
以某种方式影响此限制。
我创建了以下简单程序,它将 int
推回到 boost::fusion::vector
类型指定的次数,然后将其转换为结果到 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: error: ‘vector51’ does not name a type .../boost/fusion/container/generation/make_vector.hpp:105:25: error: ‘vector52’ does not name a type .../boost/fusion/container/generation/make_vector.hpp:105:25: error: ‘vector...’ does not name a type
显然我做的不对。如何将此限制扩展到 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()
}}
嗯..我认为除了“修补”上面的代码之外没有别的办法..
EDIT2:好吧,如果有破解的意愿,显然有一种方法(无需修改 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 测试)
关于c++ - 如何将 fusion 容器大小限制扩展到 50 以上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26355688/