5

考虑以下自动生成 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 个元素的列表!

有谁知道为什么会这样?

4

1 回答 1

5

根据文档BOOST_MPL_LIMIT_xxx_SIZE指定序列可变参数形式的限制(例如list<>);编号形式(例如)没有预定义的list42<>上限,除了编译器对模板参数数量的限制。好吧,后一种说法并不完全准确:实际上,在默认库配置中,使用预先生成的预处理标头对编号形式施加了限制;请参阅这篇文章,了解如何解除它。

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

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

于 2012-03-01T06:49:25.827 回答