生成巨大的Boost.MPL型序列

generating huge Boost.MPL type sequences

本文关键字:MPL Boost 巨大      更新时间:2023-10-16

考虑以下自动生成Boost.MPL类型序列(列表或向量)的代码。

    #include <iostream>                     // cout
    #include <boost/mpl/for_each.hpp>       // for_each
    #include <boost/mpl/identity.hpp>       // identity, make_identity
    #include <boost/mpl/int.hpp>            // int_
    #include <boost/mpl/list.hpp>           // list
    #include <boost/mpl/next.hpp>           // next
    #include <boost/mpl/push_front.hpp>     // push_front
    #include <boost/mpl/vector.hpp>         // vector
    template<size_t, typename> struct iota_n;
    template<typename Value>
    struct iota_n<0, Value>
    :
            boost::mpl::list<>      // can change this to boost::mpl::vector<>
    {};
    template<size_t N, typename Value>
    struct iota_n
    :
            boost::mpl::push_front< typename
                    iota_n< 
                            N - 1, typename
                            boost::mpl::next<Value>::type
                    >::type,
                    Value
            >
    {};
    // works for N <=  20 and boost::mpl::vector
    // works for N <= 247 and boost::mpl::list
    typedef iota_n< 247, boost::mpl::int_<0> >::type sequence;
    struct print
    {
            template<typename T>
            void operator()(boost::mpl::identity<T>)
            {
                    std::cout << T::value << "n";
            }
    };
    int main()
    {
            boost::mpl::for_each<sequence, boost::mpl::make_identity<> >(
                    print()
            );
            std::cout << BOOST_MPL_LIMIT_LIST_SIZE << 'n';         // 20 on my system
            std::cout << BOOST_MPL_LIMIT_VECTOR_SIZE << 'n';       // 20 on my system
            return 0;
    }

根据Boost.MPL文档,一个boost::mpl::list序列最多可以有BOOST_MPL_LIMIT_LIST_SIZE个元素,类似地,对于boost::mpl::vector,编译器可以最多有BOOST_MPL_LIMIT_VECTOR_SIZE个元素。在我的系统中,这两个宏的值都为20。

MSVC++2010和Boost 1.47.0确实不能生成超过20个元素的向量。然而,令人惊讶的是,它可以生成多达247个元素的列表!

有人知道为什么会发生这种事吗?

根据文档,BOOST_MPL_LIMIT_xxx_SIZE指定序列的可变形式的限制(例如list<>);编号形式(例如list42<>)除了编译器对模板参数数量的限制外,没有预定义的上限。好吧,后一种说法并不完全准确:在实践中,在默认的库配置中,对使用预生成的预处理头所施加的编号表单有一个限制;看看这篇关于如何举起它的帖子。

跟进:@rhalbersma您似乎将两个独立的概念捆绑在一起:列表元素的最大数量与list的"构造函数"的最大arity。BOOST_MPL_LIMIT_LIST_SIZE控制后者,而不是前者,两者之间实际上没有依赖关系。您上面的代码正在测试前者;最大模板arity是一个完全不同的野兽。

MPL序列首先有arity限制的原因是库必须模拟可变模板(它是在C++11之前编写的),这通常是通过将未使用的参数默认为某个辅助类型来完成的,并在构建实际序列之前提供一系列专门化来剔除那些未使用的自变量。这样做的代价是,默认参数通常会显示在错误消息中,并模糊其他所有内容,而且大量的专业化对编译时间有明显的影响。IOW,你必须在某个地方停下来,当时你似乎不太可能经常需要将20多个序列元素传递给序列的"构造函数"(如果你这样做了,那么总是有编号的形式),因此存在当前的限制。