ステートフル メタプログラミング: C ではまだ合法ですか
C のより物議を醸しているメタプログラミング手法の 1 つであるステートフル メタプログラミングは、次の概念に依存しています。メタプログラミング状態を保存および取得するための constexpr カウンター。現状では、この手法は C 14 の下で合法です。ただし、C 17 の導入でこれが変わるかどうかという疑問が生じます。
当面の問題を理解するために、次の実装を考慮してください。前の投稿:
// State storage flag template <int N> struct flag { friend constexpr int adl_flag(flag<N>&); constexpr operator int() { return N; } }; // State writer template <int N> struct write { friend constexpr int adl_flag(flag<N>) { return N; } static constexpr int value = N; }; // State reader template <int N, int = adl_flag(flag<N>{})> constexpr int read(int, flag<N>, int R = read(0, flag<N + 1>{})) { return R; } // Stateful counter template <int N = 0> constexpr int counter(int R = write<read(0, flag<0>{}) + N>::value) { return R; }
この手法は次のように使用されます:
// Check if counter is stateful with static assertion static_assert(counter() != counter(), "Your compiler is mad at you"); // Template specialization based on counter state template<int = counter()> struct S {}; // Check if template specializations differ with static assertion static_assert(!std::is_same_v<S<>, S<>, "This is ridiculous");
ただし、CWG Active Issue 2118 でステートフル メタプログラミングの合法性が疑問視されました。この問題では、フレンドを使用することが提案されています。メタプログラミング状態をキャプチャおよび取得するためのテンプレート内の関数は、その難解な性質のため、形式が正しくないとみなされるべきです。
2015 年 5 月の時点で、CWG はそのような手法を禁止すべきであることに同意しましたが、適切なメカニズムはまだ決定していません。この問題は依然として進行中であり、決定が下されるまで、ステートフル メタプログラミングは C で合法のままになります。ただし、禁止メカニズムが確立されている場合、この手法は遡って欠陥報告として宣言される可能性があります。
以上がC のステートフル メタプログラミング : C 14 の合法的な手法ですが、C 17 では変更されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。