C++ 带状态的Boost.MPL转换?

C++ 带状态的Boost.MPL转换?,c++,templates,boost-mpl,C++,Templates,Boost Mpl,我有以下mpl序列 boost::mpl::vector_c<std::size_t, 0, 1, 2, 0, 1, 0> 就我而言,结果应该是: boost::mpl::vector_c<std::size_t, 0, -1, -1, 1, -1, 2> PS:在这个实现中,输入序列中的“1”被转换为递增索引,而大于1的值被转换为std::size\u t(-1)。输入序列中不允许使用零(在别处选中) PS2:我已经检查过,实际上,boost::mpl中没有将任意m

我有以下mpl序列

boost::mpl::vector_c<std::size_t, 0, 1, 2, 0, 1, 0>
就我而言,结果应该是:

boost::mpl::vector_c<std::size_t, 0, -1, -1, 1, -1, 2>
PS:在这个实现中,输入序列中的“1”被转换为递增索引,而大于1的值被转换为std::size\u t(-1)。输入序列中不允许使用零(在别处选中)

PS2:我已经检查过,实际上,
boost::mpl
中没有将任意
mpl
序列(作为算法的结果)转换回
boost::mpl::vector
的工具。因此它是 需要为此编写代码也。。。最后,我把代码改成了

<boost/fusion/container/vector/detail/as_vector.hpp>

“规范化”类型计算结果


再次感谢你

模板元编程确实需要一些时间来适应

注意循环如何转化为递归,如果语句案例转化为模板专门化,“状态”转化为其他模板参数:

#include <cstddef>
#include <boost/mpl/print.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/size.hpp>

using boost::mpl::vector_c;
using boost::mpl::push_back;
using boost::mpl::pop_front;
using boost::mpl::front;
using boost::mpl::int_;
using boost::mpl::size;

typedef vector_c<std::size_t, 0, 1, 2, 0, 1, 0> input_sequence;

template <int i, int current>
struct next_i
{
    static const int value = i;
};

template <int i>
struct next_i<i, 0>
{
    static const int value = i + 1;
};

template <int i, int current>
struct next_output
{
    static const int value = -1;
};

template <int i>
struct next_output<i, 0>
{
    static const int value = i;
};

template <typename rest_of_input, int rest_of_input_size, int i, typename output_so_far>
struct loop
{
    typedef typename front<rest_of_input>::type current_t;
    static const int current = current_t::value;
    static const int next_i_ = next_i<i, current>::value;
    static const int next_output_ = next_output<i, current>::value; 

    typedef typename loop<
            typename pop_front<rest_of_input>::type,
            rest_of_input_size - 1,
            next_i_,
            typename push_back<output_so_far, int_<next_output_> >::type 
    >::type type;
};

template <typename rest_of_input, int i, typename output_so_far>
struct loop<rest_of_input, 0, i, output_so_far>
{
    typedef output_so_far type;
};

template <typename input>
struct algorithm
{
    typedef typename size<input>::type size_;
    typedef typename loop<input, size_::value, 0, vector_c<std::size_t> >::type type;
};

typedef algorithm<input_sequence>::type output_sequence;

int main()
{
    boost::mpl::print<output_sequence>();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用boost::mpl::vector_c;
使用boost::mpl::push_-back;
使用boost::mpl::pop_front;
使用boost::mpl::front;
使用boost::mpl::int;
使用boost::mpl::size;
类型定义向量输入序列;
模板
结构下一步(i)
{
静态常数int值=i;
};
模板
结构下一步(i)
{
静态常数int值=i+1;
};
模板
结构下一个输出
{
静态常量int值=-1;
};
模板
结构下一个输出
{
静态常数int值=i;
};
模板
结构循环
{
typedef typename front::键入当前\u t;
静态常数int current=当前值;
静态常量int next_i=next_i::value;
静态常量int next_output=next_output::value;
typedef typename循环<
typename pop_front::type,
剩余的输入大小为-1,
接下来,我,,
typename推回::type
>::类型类型;
};
模板
结构循环
{
typedef输出\u至今类型;
};
模板
结构算法
{
typedef typename size::type size\uux;
typedef typename循环::type type;
};
typedef算法::输入输出_序列;
int main()
{
boost::mpl::print();
}

这可能写得更好(可能使用
mpl::fold
)。

您希望开始使用递归重写算法。答案应该变得更清楚。可能是使用
折叠
,因为这是所有转换的基础。在MPL狂热的日子里,我学习了一点Haskell,这样我就可以在尝试将算法转换成模板之前在其中尝试我的算法。。。而
折叠
是所有循环的基础。我本来希望有更简单的东西!无论如何,IMO的答案清楚地解释了实现预期结果所需的TMP“思维”。我唯一的抱怨是,如果有的话,输出序列不是mpl::vector_c,而是一个类型为:boost::mpl::v_item的“概念等价”beast!
<boost/fusion/container/vector/detail/as_vector.hpp>
#include <cstddef>
#include <boost/mpl/print.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/size.hpp>

using boost::mpl::vector_c;
using boost::mpl::push_back;
using boost::mpl::pop_front;
using boost::mpl::front;
using boost::mpl::int_;
using boost::mpl::size;

typedef vector_c<std::size_t, 0, 1, 2, 0, 1, 0> input_sequence;

template <int i, int current>
struct next_i
{
    static const int value = i;
};

template <int i>
struct next_i<i, 0>
{
    static const int value = i + 1;
};

template <int i, int current>
struct next_output
{
    static const int value = -1;
};

template <int i>
struct next_output<i, 0>
{
    static const int value = i;
};

template <typename rest_of_input, int rest_of_input_size, int i, typename output_so_far>
struct loop
{
    typedef typename front<rest_of_input>::type current_t;
    static const int current = current_t::value;
    static const int next_i_ = next_i<i, current>::value;
    static const int next_output_ = next_output<i, current>::value; 

    typedef typename loop<
            typename pop_front<rest_of_input>::type,
            rest_of_input_size - 1,
            next_i_,
            typename push_back<output_so_far, int_<next_output_> >::type 
    >::type type;
};

template <typename rest_of_input, int i, typename output_so_far>
struct loop<rest_of_input, 0, i, output_so_far>
{
    typedef output_so_far type;
};

template <typename input>
struct algorithm
{
    typedef typename size<input>::type size_;
    typedef typename loop<input, size_::value, 0, vector_c<std::size_t> >::type type;
};

typedef algorithm<input_sequence>::type output_sequence;

int main()
{
    boost::mpl::print<output_sequence>();
}