C++ 使用带有占位符的mpl::fold和我自己的struct灾难
我有以下主要模板:C++ 使用带有占位符的mpl::fold和我自己的struct灾难,c++,templates,template-meta-programming,boost-mpl,C++,Templates,Template Meta Programming,Boost Mpl,我有以下主要模板: template<size_t pos, size_t lev> struct Sol; 模板 结构溶胶; 我专门针对一些pos值,如: template<size_t lev> struct Sol<0, lev> { static const mpl::vector_c<size_t, 4, 6> jumps; static const size_t value = mpl::fold&l
template<size_t pos, size_t lev>
struct Sol;
模板
结构溶胶;
我专门针对一些pos值,如:
template<size_t lev>
struct Sol<0, lev>
{
static const mpl::vector_c<size_t, 4, 6> jumps;
static const size_t value =
mpl::fold<jumps, mpl::integral_c<size_t, 0>,
mpl::plus<Sol<_1, lev-1>::value,
Sol<_2, lev-1>::value> >::type::value;
}
模板
结构溶胶
{
静态常量mpl::向量跳;
静态常量大小\u t值=
mpl::fold::type::value;
}
但是我得到了Sol
预期的size\u t
和mpl::\u 1
。我知道在这种情况下,我可能会忽略我试图做的折叠操作,只声明value是4和6的pos
结构的另两个Sol
的一级较低值的总和。但是我想知道如果vector\u c
输入有点长,这是否可以修复
谢谢。下面的代码将满足您的需要。我做了一些改变 首先,我用
mpl::integral\u c
包装了pos
非类型模板参数。通常,在使用Boost.MPL时,建议包装所有非类型模板参数。这样,你以后就不必区分它们了
其次,我使用了模板元函数转发。这意味着,我不是在Sol
中定义模板数据成员value
,而是从包含该值的Boost.MPL模板派生Sol
。这将节省您到处键入::type::value
。使用良好的缩进使代码更易于阅读
第三,我用一个boost::mpl::lambda
将您对mpl::plus
的调用包装在mpl::fold
内部。对于您给出的代码来说,这不是非常必要的,但是如果您在另一个带有其他占位符参数的mpl::fold
表达式中使用Sol
本身(lambda包装将延迟计算,直到解析完整个模板)
第四,我对lev
参数进行了完全专门化,以停止递归。顺便说一句,如果您开始在lev
上进行编译时计算,同样的建议也适用:首先将其包装成mpl::integral\u c
#include <boost/mpl/fold.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/vector_c.hpp>
namespace mpl = boost::mpl;
using namespace mpl::placeholders;
// primary template
template<typename pos, size_t lev>
struct Sol;
// partial specialization for zero position
template<size_t lev>
struct Sol< mpl::integral_c<size_t, 0>, lev>
:
mpl::fold<
mpl::vector_c<size_t, 4, 6>,
mpl::integral_c<size_t, 0>,
mpl::lambda<
mpl::plus<
Sol<_1, lev-1>,
Sol<_2, lev-1>
>
>
>
{};
// full specialization for zero position and level
template<>
struct Sol< boost::mpl::integral_c<size_t, 0>, 0>
:
boost::mpl::integral_c<size_t, 0> // or whatever else you need
{};
#包括
#包括
#包括
#包括
#包括
#包括
名称空间mpl=boost::mpl;
使用名称空间mpl::占位符;
//主模板
模板
结构溶胶;
//零位部分特化
模板
结构溶胶
:
折叠<
mpl::vector_c,
mpl::积分,
lambda<
mpl::plus<
索尔,
溶胶
>
>
>
{};
//零位零级全专业化
模板
结构溶胶
:
boost::mpl::integral\u c//或任何您需要的东西
{};
下面的代码将执行您想要的操作。我做了一些改变
首先,我用mpl::integral\u c
包装了pos
非类型模板参数。通常,在使用Boost.MPL时,建议包装所有非类型模板参数。这样,你以后就不必区分它们了
其次,我使用了模板元函数转发。这意味着,我不是在Sol
中定义模板数据成员value
,而是从包含该值的Boost.MPL模板派生Sol
。这将节省您到处键入::type::value
。使用良好的缩进使代码更易于阅读
第三,我用一个boost::mpl::lambda
将您对mpl::plus
的调用包装在mpl::fold
内部。对于您给出的代码来说,这不是非常必要的,但是如果您在另一个带有其他占位符参数的mpl::fold
表达式中使用Sol
本身(lambda包装将延迟计算,直到解析完整个模板)
第四,我对lev
参数进行了完全专门化,以停止递归。顺便说一句,如果您开始在lev
上进行编译时计算,同样的建议也适用:首先将其包装成mpl::integral\u c
#include <boost/mpl/fold.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/vector_c.hpp>
namespace mpl = boost::mpl;
using namespace mpl::placeholders;
// primary template
template<typename pos, size_t lev>
struct Sol;
// partial specialization for zero position
template<size_t lev>
struct Sol< mpl::integral_c<size_t, 0>, lev>
:
mpl::fold<
mpl::vector_c<size_t, 4, 6>,
mpl::integral_c<size_t, 0>,
mpl::lambda<
mpl::plus<
Sol<_1, lev-1>,
Sol<_2, lev-1>
>
>
>
{};
// full specialization for zero position and level
template<>
struct Sol< boost::mpl::integral_c<size_t, 0>, 0>
:
boost::mpl::integral_c<size_t, 0> // or whatever else you need
{};
#包括
#包括
#包括
#包括
#包括
#包括
名称空间mpl=boost::mpl;
使用名称空间mpl::占位符;
//主模板
模板
结构溶胶;
//零位部分特化
模板
结构溶胶
:
折叠<
mpl::vector_c,
mpl::积分,
lambda<
mpl::plus<
索尔,
溶胶
>
>
>
{};
//零位零级全专业化
模板
结构溶胶
:
boost::mpl::integral\u c//或任何您需要的东西
{};
谢谢,这真是太酷了!我对lambda有点困惑…为什么在这种情况下它不是“严格必要的”?我认为mpl::apply在内部使用lambda将占位符内容转换为元函数类。fold也这样做吗?我在工作中看到了元转发技巧,也很不错@如果在Sol
上执行mpl::fold
,问题就会出现,因为这样外部mpl::fold
中的\u 1
可能会与内部折叠中的\u 1
混淆。如果将Sol
用作独立对象,则没有问题,但一般来说,包装占位符更安全。boost邮件列表上有一条很长的线索。谢谢,这真的很酷!我对lambda有点困惑…为什么在这种情况下它不是“严格必要的”?我认为mpl::apply在内部使用lambda将占位符内容转换为元函数类。fold也这样做吗?我看到元向前