【问题标题】:unexpected result using boost mpl inserter iterator使用 boost mpl 插入器迭代器的意外结果
【发布时间】:2011-06-17 11:41:34
【问题描述】:

我曾期望以下内容会给出相同的结果:

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>
{};

但我无法让它工作。

非常感谢

【问题讨论】:

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


    【解决方案1】:

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

    现在,访问 mpl::range_c 中的元素已经为您提供了 mpl::int_,正如您所注意到的,因此无需尝试提取数值以将其放回。 mpl 序列上的迭代抽象为您完成。

    对于您的实际使用,您可以使用一个元函数来获取 mpl::int_ 并返回您的示例。你必须明白,没有适当的通用元编程和元 lambda 函数可以用整数类型完成,因此 mpl::int_ 抽象:

    #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() 只是为了评估我们在调用 at 后进入了正确的类类型。

    让我们回顾一下:

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

    【讨论】:

    • 王牌!很好的答案-我现在明白了-它很管用。谢谢
    • 关于占位符的 ::value,我正在开发一个允许这些的补丁,但这是 1.48 的东西;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 2016-06-18
    • 2013-10-15
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 2016-01-15
    相关资源
    最近更新 更多