# Chapter 21 - Exercises

## Exercise 1 - Basics

1. What are **unary** and **binary** functions?
2. What are **predicates**?

## Exercise 2 - Function Object Types

For each of the following functions, create a variable to store the function as a function object:

```cpp
void first() {}
```

```cpp
int second() { return 1; }
```

```cpp
int third(int x) { return x; }
```

```cpp
int fourth(int x, int y) { return x * y; }
```

## Exercise 3 - Unary Functions

### Part 1 &#x20;

Create a unary function that accumulates the values that were used to invoked it.&#x20;

```cpp
auto intAccumulator = Accumulator<int>();
intAccumulator(5);
intAccumulator(10);
intAccumulator(13);
std::cout << intAccumulator.result() << std::endl;  // Prints 28 
```

Use this function with the `std::for_each` function to accumulate all values in a vector of integers.

```cpp
auto accumulator = std::for_each(numbers.begin(), numbers.end(), Accumulator<int>());
std::cout << accumulator.sum() << std::endl;
```

Verify that the answer is correct.

{% hint style="info" %}
The `std::for_each` function returns the function object that was originally passed as the third argument.&#x20;
{% endhint %}

### Part 2

Create a unary predicate that determines whether a number is a multiple of another.&#x20;

```cpp
auto isMultiple = IsMultiple(5);
if (isMultiple(10)) {
    std::cout << "10 is a multiple of 5" << std::endl;
}
```

Use this unary predicate with the `std::find_if` function to find the first element in a vector of integers that is a multiple of a value that the user has entered.&#x20;

### Part 3

Create a unary predicate that determines whether a string begins with another string.

```cpp
auto beginsWithPre = BeginsWith("pre");
if (beginsWithPre("precondition")) {
    std::cout << "precondition begins with pre" << std::endl;
}
```

Use this unary predicate with the `std::find_if` function to find the first element in a vector of strings that begins with a string chosen by the user.&#x20;

## Exercise 4 - Binary Functions&#x20;

### Part 1&#x20;

Create a binary function that simply adds two numerical values together.&#x20;

```cpp
auto multiply = Multiply<double>();
std::cout << multiply(3.0, 4.0) << std::endl;  // Returns 12.0 
```

Use this binary function with the `std::transform` function that performs a pairwise multiplication between two vectors, and stores the results in a third result vector.

### Part 2&#x20;

Create a `Person` struct that has a string member variable `name`, and an integer member variable `age`.&#x20;

Create a binary function called `ConvertToPerson` that accepts a string parameter `name`, and an integer parameter `age`, and returns a `Person` with the given name and age.&#x20;

Create a vector of strings called `names` with three random names of your choice.

Create a vector of integers called `ages` with three random numbers of your choice.

Now, use the `std::transform` function to perform a pairwise enumeration over the `names` and `ages` vectors, to create a vector of `Persons`

```cpp
std::vector<Person> people;
people.resize(3);

std::transform(
    names.begin(),
    names.end(),
    ages.begin(),
    people.begin(),
    ConvertToPerson()
)
```

### Part 3&#x20;

Create a **binary predicate** that helps sort a vector of integers in descending order.&#x20;

```cpp
std::vector<int> numbers = {5, 10, 2, 4, 1};
std::sort(numbers.begin(), numbers.end(), DescendingSort<int>());
```
