C 14 make_integer_sequence の実装とエラー分析
概要
C 14 エイリアス テンプレートmake_integer_sequenceクラス テンプレート integer_sequence の作成が簡素化されます。この記事では、ヘルパー構造体とマクロを使用した実装について説明し、コンパイル中に発生したエラーについて説明します。
make_integer_sequence の実装
make_integer_sequence を実装するには、ヘルパー構造体 make_helper が定義されます。
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; };
実際の実装make_integer_sequence は次のようになります。
template< class T , class N > using make_integer_sequence = typename make_helper<T,N>::type;
エラー分析
GCC 4.8.0 でのコンパイルは、仮想メモリの枯渇により最初に失敗しました。このエラーは、より大きなシーケンスを生成するためにマクロ GEN が変更されたときに発生しました。この理由は、実装には深いテンプレートのインスタンス化が必要であり、使用可能なメモリが使い果たされる可能性があるためです。
テンプレートの深さのインスタンス化を減らす
深いテンプレートのインスタンス化を減らすには、次のいずれかを行います。 -ftemplate- Depth コンパイラ オプションを使用して最大深度を増やすことも、対数複雑度を備えた別の実装を使用することもできます。
Log N の実装
提供されている log N 実装は再帰的アプローチを使用しており、より効率的です:
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>{};
以上がC 14 の `make_integer_sequence` を効率的に実装し、コンパイル エラーを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。