In C 14 wurde die Aliasvorlage make_integer_sequence eingeführt, um die Erstellung der Klassenvorlage integer_sequence zu vereinfachen. Um make_integer_sequence zu implementieren, wird eine Hilfsstruktur, make_helper, verwendet.
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.
Hier entsteht das Problem. In Ihrer Implementierung verwendet die make_helper-Struktur einen rekursiven Ansatz. Obwohl dies wie eine einfache Lösung erscheint, kann es zu einem schnellen Anstieg der Vorlageninstanziierungen führen, insbesondere wenn der N-Parameter groß ist.
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; };
Aufgrund dieses exponentiellen Wachstums kann der Compiler den virtuellen Speicher schnell erschöpfen , wie Sie festgestellt haben, als Sie das GEN-Makro geändert haben, um Ganzzahlfolgen mit Vielfachen von 4 zu generieren.
Das Problem der Speichererschöpfung kann durch den Einsatz einer logarithmischen Tiefenimplementierung behoben werden. Dieser Ansatz minimiert die Anzahl rekursiver Aufrufe und verringert die Instanziierungstiefe der Vorlage.
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>{};
Bei dieser logarithmischen Tiefenimplementierung wächst die Rekursionstiefe logarithmisch mit N. Dies reduziert den Speicherverbrauch erheblich und ermöglicht die Kompilierung von Ganzzahlfolgen mit viel größeren Werten von N.
Durch die Verwendung der logarithmischen Tiefenimplementierung wird das ursprüngliche Problem der Erschöpfung des virtuellen Speichers gelöst und ermöglicht zur Erzeugung ganzzahliger Folgen mit großen Werten von N.
Das obige ist der detaillierte Inhalt vonWie können wir die „make_integer_sequence'-Implementierung von C 14 optimieren, um Speichererschöpfung zu vermeiden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!