フォールディング式

編集

フォールディング式(Fold Expressions)は、C++17で導入された機能で、可変引数テンプレートをより簡潔に扱うことができる機能です。フォールディング式には以下の4つの形式があります:

  1. 単項右折りたたみ: (... op pack)
  2. 単項左折りたたみ: (pack op ...)
  3. 二項右折りたたみ: (init op ... op pack)
  4. 二項左折りたたみ: (pack op ... op init)

主な特徴:

  • パラメータパックの要素に対して二項演算子を適用します。
  • 算術演算子、比較演算子、論理演算子などが使用可能です。
  • コードの簡潔さと可読性が向上します。
  • コンパイル時の処理が可能です。

使用例

編集

以下に、各形式の具体的な使用例を示します。

二項右折りたたみ

編集

二項右折りたたみは、初期値を指定し、パラメーターパックの要素に演算子を適用する方法です。以下は、すべての引数の積を計算する関数の例です。

#include <iostream>

// 初期値を持つ二項右折りたたみの例
template<typename... Args>
auto multiply_all(Args... args) {
    return (1 * ... * args);    // 二項右折りたたみ
}

auto main() -> int {
    std::cout << "Product: " << multiply_all(2, 3, 4) << std::endl;  // 出力: 24
    return 0;
}

二項左折りたたみ

編集

二項左折りたたみは、パラメーターパックの要素に演算子を左から右に適用し、初期値と一緒に演算を行います。以下は、数値の合計を計算する関数の例です。

#include <iostream>

// 二項左折りたたみの例
template<typename... Args>
auto sum(Args... args) {
    return (0 + ... + args);    // 二項左折りたたみ
}

auto main() -> int {
    std::cout << "Sum: " << sum(1, 2, 3, 4, 5) << std::endl;  // 出力: 15
    return 0;
}

その他のフォールディング式の例

編集

以下のコードは、フォールディング式の他の形式の使用例を示しています。

// 単項右折りたたみの例
template<typename... Args>
bool all_positive(Args... args) {
    return (... && (args > 0));    // 単項右折りたたみ
}

// 単項左折りたたみの例
template<typename... Args>
void print_all(Args... args) {
    (std::cout << ... << args) << std::endl;    // 単項左折りたたみ
}

// カンマ演算子を使用した右折りたたみの例
template<typename... Args>
void process_all(Args... args) {
    (..., (std::cout << args << " "));    // 単項右折りたたみ
    std::cout << std::endl;
}

auto main() -> int {
    // all_positive の使用例
    std::cout << "All positive: " << all_positive(1, 2, 3) << std::endl;  // 出力: true
    std::cout << "All positive: " << all_positive(1, -2, 3) << std::endl; // 出力: false

    // print_all の使用例
    print_all("Hello", ' ', "World", '!');  // 出力: Hello World!

    // process_all の使用例
    process_all(1, 2.5, "test");  // 出力: 1 2.5 test
    
    return 0;
}
まとめ

フォールディング式は、可変引数を簡潔に扱うための強力な機能です。これにより、再帰的なテンプレートメタプログラミングを避けつつ、パラメータパックを効率的に操作できます。これにより、コードがより読みやすく、メンテナンスしやすくなります。