看了一下Boost MP11中
由于
mp_with_index
的实现,它似乎通过二分搜索将运行时的值映射到编译时的常量。对于较小的值,比如遍历变体,这似乎运行良好。但是,当我用较大的值进行测试时,编译器似乎无法及时编译代码。虽然我没有对编译时间进行基准测试,但在测试5位数整数值时遇到了编译器超时值,这似乎表明编译器需要比我预期的更多的工作量。#include <boost/mp11/algorithm.hpp>
inline constexpr auto m = unsigned{99'999u};
inline constexpr auto n = unsigned{m - 1};
static_assert(boost::mp11::mp_with_index<m>(n,
[](auto r){ return decltype(r)::value == n; }));
由于
mp_with_index
使用二分搜索算法,因此时间复杂度为对数级别,我预计对于一个5位整数值,最多需要18步才能完成映射。为什么编译器似乎需要做更多的工作,而不仅仅是一些模板实例化和整数值比较呢?
实际示例
[](int){ return true; }
)时,显示的生成代码很少,并且似乎不受m
的大小影响。然而,当增加m
时,编译时间仍然显著增加,同时在m=99999
时超时。 - undefinedmp_with_index_impl_::call
函数中的i
不是constexpr
的。(函数参数从不是constexpr
的)。其中的if
语句也不是if constexpr
。(它不能是)。因此,if
语句的两个分支都会被实例化。然后,这两个实例化中的每个分支都会被实例化,以此类推,直到其中一个小型N的特化接管---然后该特化中的所有case
分支都会被实例化。 - undefinedif
分支没有标记为constexpr
,函数体中的每个模板实体都必须被实例化,这实际上导致了模板实例化的指数增长。这个对数函数的指数特性在这个上下文中相当微妙地隐藏起来了。 - undefined