`std::bind`

¶

`std::bind`

: Why?¶

**Why?** What’s the problem?

**Answer:**

Hard to explain

Best to see the problem first

Let’s start small, by simple example

**Problem: we have …**

Two dimensional points

`(x,y)`

A function to compute the distance between two points

**We want:**

A function to compute the distance from

*origin*`(0,0)`

## What We Have¶

```
struct Point
{
Point(double x, double y)
: x(x), y(y) {}
double x, y;
};
```

```
double distance(Point p, Point q)
{
return std::sqrt(
std::pow(std::abs(p.x-q.x), 2) +
std::pow(std::abs(p.y-q.y), 2)
);
}
```

## Retro C/C++¶

We have all that is needed

Could easily define a small function

⟶ Problem solved

*But this would be soo retro!*

```
double distance_origin(Point p)
{
return distance(p, {0,0});
}
```

## The Real Problem¶

**Nothing is wrong with small functions**

Compiler will inline them

… and optimize away entirely

Defined centrally (public header file?) for further reuse

**But…**

What if they serve

*only one*purpose?

Sample Problem

Compute the origin-distances of an array of points, and store
those in an equally sized array of `double`

!

## Straightforward Implementation¶

Near the top of the implementation file …

```
static double distance_origin(Point p) {
return distance(p, {0,0});
}
```

And *far down below*, in the implementation section …

```
double distances_origin[sizeof(swarm)/sizeof(Point)];
std::transform(swarm, swarm+sizeof(swarm)/sizeof(Point),
distances_origin,
distance_origin);
```

## More Sample Problems¶

Another Sample Problem

Compute the distances of an array of points from a given point, and
store those in an equally sized array of `double`

!

*Possible solutions*: as many as there are different tastes around …

Lets write another stupid function, basically a copy of

`distance_origin`

- only with`(1,1)`

instead of`(0,0)`

Even better: lets generalize!

*Functors!**Function call operator!*

## More Straightforward Implementations¶

```
struct distance_point {
distance_point(Point origin) : origin(origin) {}
double operator()(Point p) const {
return distance(p, origin);
}
Point origin;
};
```

```
double distances_origin[sizeof(swarm)/sizeof(Point)];
std::transform(swarm, swarm+sizeof(swarm)/sizeof(Point),
distances_point,
distance_point({1,1}));
```

## Readability¶

*Provided that the helper code is only used once …*

*Readability*is inversely proportional to amount of code*Number of bugs*is directly proportional to amount of codeHelper implementation is nowhere near location of use

`static`

is the only keyword that enhances readability

*Similar problem with many data structures and algorithms …*

Sorting criteria:

`std::sort`

,`std::map`

, …Predicates:

`std::find_if`

,`std::equal`

, …Arbitrary adaptations where helper functions are needed

Most prominent (although relatively useless nowadays):

`std::for_each`

## Introducing `std::bind`

(1)¶

*Best done by example …*

```
void f(int a, int b)
{
std::cout << a << ',' << b << std::endl;
}
```

```
f(1, 2);
``` |
```
1,2
``` |

**What if** we need the functionality of `f(a, b)`

, but are required
to pass a *callable* that takes no parameters?

## Introducing `std::bind`

(2)¶

**In other words**, we need to create a function-like object that
wraps `f(a,b)`

that always calls `f`

with, say, `a=1`

and
`b=2`

.

```
auto bound = std::bind(f, 1, 2);
bound();
``` |
```
1,2
``` |

Alternative: manually write function adaptor (functor) that remembers parameters until called

Origin: Boost (www.boost.org)

## Introducing `std::bind`

(3)¶

**Routing parameters into arbitrary positions:** `std::placeholders`

```
auto bound = std::bind(f, 42, std::placeholders::_1);
bound(7);
``` |
```
42,7
``` |

```
auto bound = std::bind(f,
std::placeholders::_2,
std::placeholders::_1);
bound(1,2);
``` |
```
2,1
``` |

## Applying `std::bind`

(1)¶

**So how does this apply to our ``std::transform`` problem?**

Readability: we want to eliminate those annoying extra helper functions

Want to wrap existing

`double distance(Point, Point)`

which is similar in purpose but does not fit exactly

**What we have …**

```
struct Point {...};
double distance(Point, Point);
```

**What we want …**

```
std::transform(swarm, swarm+sizeof(swarm)/sizeof(Point),
distances_point,
SOMETHING WHICH TAKES ONE POINT);
```

## Applying `std::bind`

(2)¶

```
std::transform(swarm, swarm+sizeof(swarm)/sizeof(Point),
distances_origin,
std::bind(distance, Point{0,0}, std::placeholders::_1));
```

```
// this is exactly the same as above
```

**Summary**

Readability: what remains unreadable is only the language itself

Have to get used to

`std::bind`

`std::bind`

vs. Lambda¶

**Lambdas are usually a better alternative** …

```
std::transform(swarm, swarm+sizeof(swarm)/sizeof(Point),
distances_origin,
[](Point p) { return distance({0,0}, p); });
```

A more advanced exercise

Use `std::sort`

to sort an array of points by their distance to a
given point.

## A Bigger Picture: Types¶

**What about types?**

Goal is to have

*no runtime overhead*⟶

*Late binding (polymorphism)*ruled out⟶ No common base class

Only the call signatures (parameter and return types) are the same

**What does this mean?**

Perfect for

`<algorithm>`

which is also designed for speedHave to be careful when code size is important

Client code has to be instantiated with the type

**Tradeoff**: speed, code size, elegance, design, taste …