在 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中文網其他相關文章!