在 C 14 中,引入了 make_integer_sequence 别名模板来简化 integer_sequence 类模板的创建。为了实现 make_integer_sequence,需要使用辅助结构 make_helper。
template< class T, T... I> struct integer_sequence { typedef T value_type; static constexpr size_t size() noexcept { return sizeof...(I) ; } }; template< class T, T N> using make_integer_sequence = integer_sequence< T, 0,1,2, ... ,N-1 >; // only for illustration.
这就是问题出现的地方。在您的实现中,make_helper 结构使用递归方法。虽然这看起来像是一个简单的解决方案,但它可能会导致模板实例化的快速增加,特别是当 N 参数很大时。
template< class T, T N, T... I > struct make_helper { typedef typename mpl::if_< T(0) == N, mpl::identity< integer_sequence<T,I...> >, make_helper< T, N-1, N-1,I...> >::type; };
由于这种指数级增长,编译器可以快速耗尽虚拟内存,正如您在更改 GEN 宏以生成 4 倍数的整数序列时遇到的那样。
内存耗尽问题可以通过采用对数深度实现来解决。这种方法最大限度地减少了递归调用的次数,从而减少了模板实例化深度。
template<unsigned...> struct seq{ using type = seq; }; template<class S1, class S2> struct concat; template<unsigned... I1, unsigned... I2> struct concat<seq<I1...>, seq<I2...>> : seq<I1..., (sizeof...(I1)+I2)...>{}; template<class S1, class S2> using Concat = Invoke<concat<S1, S2>>; template<unsigned N> struct gen_seq; template<unsigned N> using GenSeq = Invoke<gen_seq<N>>; template<unsigned N> struct gen_seq : Concat<GenSeq<N/2>, GenSeq<N - N/2>>{}; template<> struct gen_seq<0> : seq<>{}; template<> struct gen_seq<1> : seq<0>{};
在这种对数深度实现中,递归深度随 N 对数增长。这显着减少了内存消耗,并允许编译N 值更大的整数序列。
通过采用对数深度实现,解决了原来的虚拟内存耗尽问题,允许生成具有较大 N 值的整数序列。
以上是我们如何优化 C 14 的 `make_integer_sequence` 实现以避免内存耗尽?的详细内容。更多信息请关注PHP中文网其他相关文章!