使用boost mpl inserter迭代器的意外结果

时间:2011-06-17 11:41:34

标签: c++ boost iterator metaprogramming boost-mpl

我原本期望以下内容给出相同的结果:

namespace mpl = boost::mpl;

template<int from, int to>
struct
make_vector1
 : mpl::copy<
     mpl::range_c<int,from,to>, 
     mpl::inserter< 
       mpl::vector<>,
       mpl::push_back<mpl::placeholders::_1,
              mpl::placeholders::_2 // <- Copy int_ types
             >
       > 
     >  
{};

template<int from, int to>
struct
make_vector2 
 : mpl::copy<
     mpl::range_c<int,from,to>, 
     mpl::inserter< 
       mpl::vector<>,
       mpl::push_back<mpl::placeholders::_1,
              mpl::int_<mpl::placeholders::_2::value> // <- Alternative?
              >
       > 
     >
{};

但他们没有。

int
main  (int ac, char **av)
{
  typedef make_vector1<0,3>::type v1;
  typedef make_vector2<0,3>::type v2;

  //returns 0, as I would expect
  std::cout<<"I1 = "<<mpl::at<v1,mpl::int_<0> >::type::value <<std::endl;

  //returns 2, which has me stumpted.
  std::cout<<"I2 = "<<mpl::at<v2,mpl::int_<0> >::type::value <<std::endl;
}

知道这里发生了什么吗?

我想使用第二种方法构造Example类型的mpl :: vector,其中:

template<int i>
struct Example : mpl::int_<i>
{};

但我无法让它发挥作用。

非常感谢

1 个答案:

答案 0 :(得分:4)

你得到一个2因为_2上的值被定义为2(占位符索引)。由于显而易见的原因,MPL没有在占位符上定义::所以你不能直接这样做。

现在,访问mpl :: range_c中的元素已经为您提供了一个mpl :: int_,因为您没有必要尝试提取数值来将其放回去。对mpl序列的迭代抽象为你做了。

对于您的实际使用情况,您可以使用元函数获取mpl :: int_并返回您的示例。你必须掌握没有适当的通用元编程或meta-lambda函数可以用整数类型完成,因此mpl :: int_ abstraction:

#include <boost/mpl/at.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/push_back.hpp>

namespace mpl = boost::mpl;

template<int I> struct Example : boost::mpl::int_<I> 
{
  static void foo() { std::cout << "**" << I << "**\n";}
};

template<class T> struct make_example
{
  typedef Example<T::value> type;
};

template<int from, int to>
struct
make_vector2 
 : mpl::copy<
     mpl::range_c<int,from,to>, 
     mpl::inserter< 
       mpl::vector<>,
       mpl::push_back<mpl::placeholders::_1,
              make_example<mpl::placeholders::_2> // <- Alternative?
              >
       > 
     >
{};

int main(int ac, char **av)
{
  typedef make_vector2<0,3>::type v2;

  mpl::at<v2,mpl::int_<0> >::type::foo();
}

我添加了foo()只是为了评估我们在调用。

之后进入正确的类类型

让我们回顾一下:

  • 整数模板参数很狡猾,这就是MPL使用int_的原因。每个整数常量序列实际上都返回int_以保持抽象级别。
  • 占位符具有:: value用于内部目的,因此您的初始结果为
  • 任何元函数都可以通过用占位符实例化而变成lambda。