可変個引数テンプレート: 反復のためのパック拡張の解明
可変個引数テンプレートは C で驚くべき表現力を与えますが、その領域に踏み込んでみると、予期せぬ複雑さが明らかになる可能性があります。このような課題の 1 つは、パック拡張を使用してパラメーター パックを反復しようとするときに発生します。次のコードを考えてみましょう:
template<typename T> static void bar(T t) {} template<typename... Args> static void foo2(Args... args) { (bar(args)...); } int main() { foo2(1, 2, 3, "3"); return 0; }
このコードはコンパイル時にエラー「'args': パラメータ パックはこのコンテキストで展開する必要があります。」というエラーが発生します。この問題は、関数呼び出しでパラメータ パックを直接展開できないことが原因です。
解決策は、そのような展開を明示的に許可するコンテキストである、braced-init-list 内でパック展開を利用することにあります。ダミー配列の初期化子リスト内に展開を配置することで、目的の動作を強制できます:
template<typename... Args> static void foo2(Args &&... args) { int dummy[] = { 0, ( (void) bar(std::forward<Args>(args)), 0) ... }; }
この改訂されたコードは、正しい評価を保証するための細心の注意を払ったアプローチを採用しています:
C 17 では、fold 式によりさらにコンパクトなソリューションが提供されます。
((void) bar(std::forward<Args>(args)), ...); ``` This approach guarantees the desired left-to-right expansion unequivocally.
以上がパック拡張を使用して C でパラメータ パックを反復するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。