Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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++ 使用带有占位符的mpl::fold和我自己的struct灾难_C++_Templates_Template Meta Programming_Boost Mpl - Fatal编程技术网

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也这样做吗?我看到元向前