Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Fold expressions(since C++17)

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Expressions
      General
      Literals
      Operators
      Conversions
       
       

      Reduces (folds) apack over a binary operator.

      Contents

      [edit]Syntax

      (pack op... ) (1)
      ( ...op pack) (2)
      (pack op...op init) (3)
      (init op...op pack) (4)
      1) Unary right fold.
      2) Unary left fold.
      3) Binary right fold.
      4) Binary left fold.
      op - any of the following 32binary operators:+-*/%^&|=<><<>>+=-=*=/=%=^=&=|=<<=>>===!=<=>=&&||,.*->*. In a binary fold, bothops must be the same.
      pack - an expression that contains an unexpandedpack and does not contain an operator withprecedence lower than cast at the top level (formally, acast-expression)
      init - an expression that does not contain an unexpandedpack and does not contain an operator withprecedence lower than cast at the top level (formally, acast-expression)

      Note that the opening and closing parentheses are a required part of the fold expression.

      [edit]Explanation

      The instantiation of afold expression expands the expressione as follows:

      1) Unary right fold(Eop...) becomes(E1op(...op(EN-1opEN)))
      2) Unary left fold(...opE) becomes(((E1opE2)op ...)opEN)
      3) Binary right fold(Eop...opI) becomes(E1op(...op(EN−1op(ENopI))))
      4) Binary left fold(Iop...opE) becomes((((IopE1)opE2)op ...)opEN)

      (whereN is the number of elements in the pack expansion)

      For example,

      template<typename...Args>bool all(Args...args){return(...&& args);} bool b= all(true,true,true,false);// within all(), the unary left fold expands as//  return ((true && true) && true) && false;// b is false

      When a unary fold is used with a pack expansion of length zero, only the following operators are allowed:

      1) Logical AND (&&). The value for the empty pack istrue.
      2) Logical OR (||). The value for the empty pack isfalse.
      3) The comma operator (,). The value for the empty pack isvoid().

      [edit]Notes

      If the expression used asinit or aspack has an operator withprecedence below cast at the top level, it must be parenthesized:

      template<typename...Args>int sum(Args&&...args){//  return (args + ... + 1 * 2);   // Error: operator with precedence below castreturn(args+ ...+(1*2));// OK}
      Feature-test macroValueStdFeature
      __cpp_fold_expressions201603L(C++17)Fold expressions

      [edit]Example

      Run this code
      #include <climits>#include <concepts>#include <cstdint>#include <iostream>#include <limits>#include <type_traits>#include <utility>#include <vector> // Basic usage, folding variadic arguments over operator<<template<typename...Args>void printer(Args&&...args){(std::cout<< ...<< args)<<'\n';} // Folding an expression that uses the pack directly over operator,template<typename...Ts>void print_limits(){((std::cout<<+std::numeric_limits<Ts>::max()<<' '), ...)<<'\n';} // Both a fold over operator&& using the pack// and over operator, using the variadic argumentstemplate<typename T,typename...Args>void push_back_vec(std::vector<T>& v, Args&&...args){    static_assert((std::is_constructible_v<T, Args&&>&& ...));(v.push_back(std::forward<Args>(args)), ...);} // Using an integer sequence to execute an expression// N times by folding a lambda over operator,template<class T,std::size_t...dummy_pack>constexpr T bswap_impl(T i,std::index_sequence<dummy_pack...>){    T low_byte_mask=static_cast<unsignedchar>(-1);    T ret{};([&]{(void)dummy_pack;        ret<<=CHAR_BIT;        ret|= i& low_byte_mask;        i>>=CHAR_BIT;}(), ...);return ret;} constexprauto bswap(std::unsigned_integralauto i){return bswap_impl(i,std::make_index_sequence<sizeof(i)>{});} int main(){    printer(1,2,3,"abc");    print_limits<uint8_t, uint16_t, uint32_t>(); std::vector<int> v;    push_back_vec(v,6,2,45,12);    push_back_vec(v,1,2,9);for(int i: v)std::cout<< i<<' ';std::cout<<'\n';     static_assert(bswap<std::uint16_t>(0x1234u)== 0x3412u);    static_assert(bswap<std::uint64_t>(0x0123456789abcdefull)== 0xefcdab8967452301ULL);}

      Output:

      123abc255 65535 4294967295 6 2 45 12 1 2 9

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 7.5.6 Fold expressions [expr.prim.fold]
      • C++20 standard (ISO/IEC 14882:2020):
      • 7.5.6 Fold expressions [expr.prim.fold]
      • C++17 standard (ISO/IEC 14882:2017):
      • 8.1.6 Fold expressions [expr.prim.fold]

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 2611C++17the expansion results of fold expressions were not enclosed with parenthesesenclosed with parentheses
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/fold&oldid=178139"

      [8]ページ先頭

      ©2009-2025 Movatter.jp