【发布时间】:2012-02-29 23:09:56
【问题描述】:
考虑以下自动生成 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 个元素的列表!
有人知道为什么会这样吗?
【问题讨论】:
-
只是一个猜测,但我认为实现 mpl 向量比仅包含一个简单的两个参数模板的链表更困难,并且涉及更多的元编程。考虑到更简单的模板和可能更少的实例化、更少的静态递归和分支,mpl 列表能够处理更多元素,这对我来说并不奇怪。
-
那么在这种情况下,为什么限制向量和列表序列的宏不一样呢?在我的系统上,两者都是 20,但我可以生成多达 247 个元素的列表!
-
这些宏设置了实际限制,这可能是基于 boost 作者通常可以在各种编译器中安全支持的内容。您可以使用 list 进行检查的事实可能仍然超出了 boost 作者希望您编写可移植代码的范围。
-
换句话说,您可以在您现在使用的任何编译器(MSVC 2010)上使用您的 mpl 列表执行 247 个列表条目,但您可能无法移植它许多不同编译器的代码。每个都有不同的限制,这些宏可能是基于作者在各种编译器中发现的实际限制。
标签: c++ boost-mpl template-meta-programming