# std::bind¶

## std::bind: Why?¶

Why? What’s the problem?

• 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¶

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

Distance
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!

Distance from Origin
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 …

One-Time Function Definition
static double distance_origin(Point p) {
return distance(p, {0,0});
}


And far down below, in the implementation section …

Location of use
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¶

One-Time Functor Definition
struct distance_point {
distance_point(Point origin) : origin(origin) {}
double operator()(Point p) const {
return distance(p, origin);
}
Point origin;
};

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


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 code

• Helper 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;
}

 Direct function call¶ f(1, 2);  prints …¶ 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.

 Hardcoded parameters auto bound = std::bind(f, 1, 2); bound();  prints …¶ 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

 Hardcoding only second parameter auto bound = std::bind(f, 42, std::placeholders::_1); bound(7);  prints …¶ 42,7 
 Exchanging parameters auto bound = std::bind(f, std::placeholders::_2, std::placeholders::_1); bound(1,2);  prints …¶ 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)¶

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

Distances from any point
// this is exactly the same as above


Summary

• 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); });


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

## A Bigger Picture: 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 speed

• Have to be careful when code size is important

• Client code has to be instantiated with the type

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