C++23 Fold Algorithms

Using Fold with Custom Data Types

Can fold_left() and fold_right() be used with custom data types?

Abstract art representing computer programming

Yes, fold_left() and fold_right() can be used with custom data types, provided that the custom data type supports the required binary operation.

Requirements for Custom Data Types

  • The custom data type must support the operation used in the fold function. This means that if you are using std::plus<>, your custom type must have an operator+.
  • The initial value and the elements in the range must be compatible with the binary operation.

Example

Let’s create a custom data type Accumulator that supports the addition operation. We’ll use this type with fold_left() to demonstrate how folding works with custom data types.

#include <algorithm>
#include <iostream>
#include <vector>

struct Accumulator {
  int sum;
  int count;

  Accumulator operator+(int n) const {
    return Accumulator{sum + n, count + 1}; }

  void log() const {
    std::cout << "Count: " << count
      << "\nSum: " << sum << "\n";
  }
};

int main() {
  std::vector<int> numbers{1, 2, 3, 4, 5};

  Accumulator result = std::ranges::fold_left(
    numbers, Accumulator{}, std::plus<>());

  result.log();
}
Count: 5
Sum: 15

Explanation

  • The Accumulator struct has two members: sum and count.
  • We define the operator+ to allow adding an integer to an Accumulator object, which updates the sum and count.
  • The log() function is used to print the current state of the Accumulator.

In the main() function, we use std::ranges::fold_left() to combine elements of the numbers vector using an Accumulator as the initial value. The custom operator+ ensures that each element of the vector is added to the Accumulator, updating the sum and count accordingly.

Using Different Operations

You can also define other operations for your custom data types. For example, if you have a custom type that represents a complex number, you can define an operator* for multiplication and use it with fold_left().

#include <algorithm>
#include <iostream>
#include <vector>

struct Complex {
  double real;
  double imag;

  Complex operator*(const Complex& other) const {
    return Complex{
      real * other.real - imag * other.imag,
      real * other.imag + imag * other.real
    };
  }
};

int main() {
  std::vector<Complex> numbers{
    {1, 2}, {3, 4}, {5, 6}};

  Complex initial{1, 0};
  Complex result = std::ranges::fold_left(
    numbers, initial, std::multiplies<>());

  std::cout << "Result: (" << result.real
    << ", " << result.imag << ")";
}
Result: (-85, 20)

In summary, fold_left() and fold_right() can be used with custom data types as long as the required operations are defined. This allows for flexible and powerful ways to process collections of custom objects.

This Question is from the Lesson:

C++23 Fold Algorithms

An introduction to the 6 new folding algorithms added in C++23, providing alternatives to std::reduce and std::accumulate

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

C++23 Fold Algorithms

An introduction to the 6 new folding algorithms added in C++23, providing alternatives to std::reduce and std::accumulate

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved