This is a series of examples that demonstrate how to get the sum of a vector of primitives, then objects, and finally shared pointers to objects. It starts with one typical way of accomplishing the task. It then goes into several more examples. The final example will probably seem like quite a huge leap over the next to last example. At that point, there will be another series of examples that builds up to that final example.

Requirements

These examples use The Eclipse CDT, mingw, CppUTest 2.1 and gcc 4.4. If you need to setup the entire environment, here are those steps:

Here is a trivial example of creating a sum over a vector of ints: SummingVectorOfInts.cpp

#include <vector>#include <CppUTest/TestHarness.h>
TEST_GROUP(vector_ints){};typedef std::vector<int> v_ints;typedef v_ints::iterator iterator;
TEST(vector_ints, manually){
v_ints values;
values.push_back(1);
values.push_back(5);
values.push_back(7);int result =0;for(iterator i = values.begin(); i != values.end();++i)
result +=*i;
LONGS_EQUAL(13, result);}

This first example simply demonstrates the mechanics of manually summing up the values of integers. The final result looks quite a bit different. Before we even get there, however, let's move on to vectors with objects rather than primitives.

Vector of Objects

Here is the same thing with a vector of objects:

SummingVectorExample1.cpp

#include <algorithm>#include <vector>#include <CppUTest/Testharness.h>struct Value_1 {
Value_1(int v): v(v){}int v;};typedef std::vector<Value_1> v_Value_1;typedef v_Value_1::iterator iterator;
TEST_GROUP(SummingVectorsExample1){};
TEST(SummingVectorsExample1, manual_sum){
v_Value_1 values;
values.push_back(Value_1(1));
values.push_back(Value_1(7));
values.push_back(Value_1(5));int result =0;for(iterator i = values.begin(); i != values.end();++i)
result +=(*i).v;
LONGS_EQUAL(13, result);}

This code seems barely different enough to warrant a whole example. Even so, I'm trying to show the background material you'll need to know to understand the final version. There are several steps along the way.

Using accumulate with vector of ints

The standard library includes std::accumulate that accomplishes what we've already shown with std::for_each. Back to primitives before moving to the object: AccumulateVectorOfInts.cpp

How does this work? Accumulate iterates over each element of the collection. On the first iteration it adds the "seed" value, which is 0, to the first value in the vector, which is 1. 0 + 1 -> 1, which becomes the new seed value. On the second loop, the seed value is 1, and the second value is 5. 5 + 1 -> 6, which becomes the new seed value. On the final time through the loop, the value 6 is added to the final value in the collection, 7. 6 + 7 -> 13.

In fact, the underlying algorithm uses + to add the values. The seed value is an int. The vector contains ints. The built-in + operator takes two ints and returns an int, so everything works as expected.

Using accumulate with vectors of objects with custom operator+

Now that you've seen the basic algorithm, let's move on to a vector of objects: SummingVectorsExample2.cpp

The accumulate algorithm needs a + operator that can take the seed value (an int in this case), and a value from the vector (a Value_2 object), add the results and return a value eequivalent to the seed type. That's what this function does:

int operator+(constint&sum, const Value_2 ¤t){return sum + current.v;}

This certainly works, but can we do any better than having to write a function? This seems like a common problem.

Using accumulate with vectors of objects with conversion operator

Another option is to provide a conversion operator. Since we are doing something simple, adding ints, this happens to work: SummingVectorsExample3.cpp

This works, as mentioned, because all the code is trying to sum on ints stored in an object. However, a conversion operator only works if there's only one way to get an appropriate value. If there were two int values, which would the conversion operator return? There are ways to make that work, but there's an even better way.

Using accumulate and calling a member

This is going to be a bit of a leap. After this, there's a series of much smaller steps showing how to get to the final version. SummingVectorsExample4.cpp

What?! This is the large leap mentioned above. In a nutshell, the code passes in a function object, std::plus<int>(), that takes 2 parameters. The first parameter, being the seed (or sum), which is an int, is handled as is (_1). The second parameter is acquired by calling the instance member Value_4::getValue().

That complex expresion is a composition of function objects.

Building up to the Complex Composition & Beyond

The final version is a huge jump from the immediately proceeding version. How can we go from one to the next?

This is Where C++0x comes into play

These next examples use type inference, one of the features in C++0x. If you followed the steps mentioned above, you'll be able to take this code as is and get it to compile. (All of the examples here come from compiling code with all of the tests passing.)

Notice that the Value class has both getValue() and operator int(). The conversion operator (operator int()) is used in one of the examples but not the final version.)

Calling the functor Directly

This first test demonstrates simply calling add with two arguments:

TEST(plusAndBind, callDirectly){
Value v(42);
std::plus<int> add;int result = add(10, v.getValue());
LONGS_EQUAL(52, result);}

This works becausestd::plus implementsoperator(). This is significant because when an instance ofstd::plus is passed into a template method, the template method can execute it as if it were a function. Consider the following:

int foo(int a, int b){return a + b;}int bar(){return foo(10, 42);}int baz(){int(*f_pointer)(int,int)= foo;return f_pointer(10, 42);}int muchBetter(){
std::plus<int> functor;return functor(10, 42);}

Initially, theres a definition forfoo, which simply adds two values. The functionbar callsfoo directly. The functionbaz creates a pointer to a function, calledf_pointer, and initializes it withfoo. It then callsfoo through the pointer to a function.

The functionmuchBetter demonstrates the same thing using a functor,std::plus, that has anoperator() as part of its definition.

Why all of this background? Well what if I have the following template method:

This template method,execute, imposes one requirement on its type F; Instances of f must respond tooperator(). A function likefoo does, as demonstrated in the first line ofcallBoth. The instance of the functorstd::plus<int> also responds tooperator(). This code compiles and defines two implementations of theexecute function.

Binding Both Parameters

Notice how the template methodexecute hard-codes the values of the parameters called on eitherfoo orstd::plus<int>? This is called Currying. This code demonstrates the same thing usingboost::bind:

TEST(plusAndBind, bindBothParameters){
Value v(42);
std::plus<int> add;auto functor = bind(add, 10, v.getValue());int result = functor();
LONGS_EQUAL(52, result);}

The call toboost::bind creates an instance of a functor, which is stored in a type-inferred variable called functor (this name is meant to be self-explaining, but is otherwise not significant). This instance internally stores three things:

A copy of add

A copy of 10

A copy of the result of calling v.getValue(), or 42.

Since the two parameters required by std::plus have been stored internally, executingfunctor requires no parameters.

Binding the second parameter

What if we want to bind the second parameter, but allow the first one to be provided by the caller:

TEST(plusAndBind, bindSecondParameter){
Value v(42);
std::plus<int> add;auto functor = bind(add, _1, v.getValue());int result = functor(10);
LONGS_EQUAL(52, result);}

This accomplishes that. Note that we could use std::bind1st. I prefer boost::bind because it's more general and works well with other parts of the boost library. In this case, the object returned from bind:

Stores add

Stores _1, which really means use the first parameter passed into the call of operator()

Stores the result of calling v.getValue(), which is 42.

Notice the call tofunctor(10). 10 is the first, and only, parameter. The expression _1 from before will bind to that value.

Binding no parameters

What if you want to just simply wrap thestd::plus<int> instance:

TEST(plusAndBind, doNotBindAnyParameters){
Value v(42);
std::plus<int> add;auto functor = bind(add, _1, _2);int result = functor(10, v.getValue());
LONGS_EQUAL(52, result);}

This example does that. This time, the return frombind:

Stores add

Stores _1, which will bind to the first parameter passed intooperator()

Stores _2, which will bind to the second parameter passed intooperator()

Notice the call tofunctor(10, 42). 10 is the first parater, which binds to _1. 42 is the second parameter, which binds to _2.

Binding the second parameter to a method call

Now things get more complex, and realistic. Rather than calling v.getValue() directly, we'll instead provide a binding to a call to v.getValue(). The call to v.getValue() was happeningbefore the creation of the functor, in fact, even before the call toboost::bind. Now it will happenafter the creation of the functor. In fact, it will be calledduring the execution of operator():

TEST(plusAndBind, bind2ndParameterToMethodCall){
Value v(42);
std::plus<int> add;auto functor = bind(add, _1, bind(&Value::getValue, _2));int result = functor(10, v);
LONGS_EQUAL(52, result);}

As before, the functor returned frombind:

Stores add

Stores _1, which is a reference the the first parameter passed into operator()

Now, however, it also stores the result ofbind(&Value::getValue, _2), which is functor object that:

Stores a pointer to a member function, Value::getValue

Refers to _2, which is the second parameter passed in to the outer-most call ofoperator().

This is a game-changer. Notice that rather than callingfunctor(10, v.getValue()), this is instead callingfunctor(10, v). When theoperator() method executes, it binds 10 to _1. It binds the result of callingoperator() onbind(&Value::getValue, _2) to _2. So here's what happens (not necessarily in this order):

Theoperator() function first associates 10 with _1 (in reality, _1 is itself a function objects that accesses the first parameter passed into theoperator() method).

Theoperator() function callsoperator() on the functor returned from the inner-most call tobind. This calls the methodValue::getValue on v, which returns 42 from v. This value, 42, is associated with the final version of _2.

10 and 42 are then passed intostd::plus<int>::operator(), which returns 52.

How you're probably write this in practice

This is how you'd probably write this in practice:

TEST(plusAndBind, theWholeThingInline){
Value v(42);auto functor = bind(std::plus<int>(), _1, bind(&Value::getValue, _2));int result = functor(10, v);
LONGS_EQUAL(52, result);}

Return toaccumulate

With that background, we can now return toaccumulate on an array of Value objects:

TEST(plusAndBind, accumulateAnArrayOfValues){
std::plus<int> add;
Value values[]={ Value(10), Value(42)};int result = std::accumulate(
values,
values +sizeof(values)/sizeof(values[0]),
0,
add
);
LONGS_EQUAL(52, result);}

This invocation ofstd::accumulate makes use of the conversion operatorValue::operator int(). As mentioned above, this is not what we want to do. We want to call a method on each instance of value in the array, choses at the time the call tostd::accumulate occurs. However, you already know how to do this from the immediately proceeding example.

In practice, using a temporary is not how you'd probably write this code:

TEST(plusAndBind, accumulateHowYoudProbablyWriteIt){
Value values[]={ Value(10), Value(42)};int result = std::accumulate(
values,
values +sizeof(values)/sizeof(values[0]),
0,
bind(std::plus<int>(), _1, bind(&Value::getValue, _2)));
LONGS_EQUAL(52, result);}

Working with vectors of shared_ptr

Let's look at one final example. Imagine you want to have a vector of dynamically-allocated objects. Instead of storing raw pointers, you might think to use some kind of smart pointer, such asstd::auto_ptr. However, you cannot putstd::auto_pointer into standard collections. So instead, you decide to useboost::shared_ptr. Here's a final example that does all of that:

This is a place whereboost::bind shines overstd::bind1st (orstd::bind2nd). It's smart enough to just work in this situation. This example is packed with a lot of details:

Using typedefs to give (hopefully) better names to types.

Dynamic allocation without an apparent deallocation by usingboost::shared_ptr

Function currying and nesting

An actual, executing and passing unit test.

The Whole File

Each of these examples are pulled from one larger, compiling C++ source file. Here's the whole file: PlusAndBindTest.cpp

#include <boost/bind.hpp>#include <numeric>#include <boost/shared_ptr.hpp>#include <CppUTest/TestHarness.h>using boost::bind;struct Value {
Value(int v): v(v){}int getValue()const{return v;}
operator int(){return v;}int v;};
TEST_GROUP(plusAndBind){};
TEST(plusAndBind, callDirectly){
Value v(42);
std::plus<int> add;int result = add(10, v.getValue());
LONGS_EQUAL(52, result);}
TEST(plusAndBind, bindBothParameters){
Value v(42);
std::plus<int> add;auto functor = bind(add, 10, v.getValue());int result = functor();
LONGS_EQUAL(52, result);}
TEST(plusAndBind, bindSecondParameter){
Value v(42);
std::plus<int> add;auto functor = bind(add, _1, v.getValue());int result = functor(10);
LONGS_EQUAL(52, result);}
TEST(plusAndBind, doNotBindAnyParameters){
Value v(42);
std::plus<int> add;auto functor = bind(add, _1, _2);int result = functor(10, v.getValue());
LONGS_EQUAL(52, result);}
TEST(plusAndBind, bind2ndParameterToMethodCall){
Value v(42);
std::plus<int> add;auto functor = bind(add, _1, bind(&Value::getValue, _2));int result = functor(10, v);
LONGS_EQUAL(52, result);}
TEST(plusAndBind, theWholeThingInline){
Value v(42);auto functor = bind(std::plus<int>(), _1, bind(&Value::getValue, _2));int result = functor(10, v);
LONGS_EQUAL(52, result);}
TEST(plusAndBind, accumulateAnArrayOfValues){
std::plus<int> add;
Value values[]={ Value(10), Value(42)};int result = std::accumulate(
values,
values +sizeof(values)/sizeof(values[0]),
0,
add
);
LONGS_EQUAL(52, result);}
TEST(plusAndBind, accumulateOnArrayUsingBind){auto functor = bind(std::plus<int>(), _1, bind(&Value::getValue, _2));
Value values[]={ Value(10), Value(42)};int result = std::accumulate(
values,
values +sizeof(values)/sizeof(values[0]),
0,
functor
);
LONGS_EQUAL(52, result);}
TEST(plusAndBind, accumulateHowYoudProbablyWriteIt){
Value values[]={ Value(10), Value(42)};int result = std::accumulate(
values,
values +sizeof(values)/sizeof(values[0]),
0,
bind(std::plus<int>(), _1, bind(&Value::getValue, _2)));
LONGS_EQUAL(52, result);}#include <vector>#include <boost/shared_ptr.hpp>typedef boost::shared_ptr<Value> sp_Value;typedef std::vector<sp_Value> vsp_Value;
TEST(plusAndBind, vsp_Value){
vsp_Value values;
values.push_back(sp_Value(new Value(10)));
values.push_back(sp_Value(new Value(42)));int result = std::accumulate(
values.begin(),
values.end(),
0,
bind(std::plus<int>(), _1, bind(&Value::getValue, _2)));
LONGS_EQUAL(52, result);}

## Table of Contents

## Overview

This is a series of examples that demonstrate how to get the sum of a vector of primitives, then objects, and finally shared pointers to objects. It starts with one typical way of accomplishing the task. It then goes into several more examples. The final example will probably seem like quite a huge leap over the next to last example. At that point, there will be another series of examples that builds up to that final example.## Requirements

These examples use The Eclipse CDT, mingw, CppUTest 2.1 and gcc 4.4. If you need to setup the entire environment, here are those steps:## Getting Started

Here is a trivial example of creating a sum over a vector of ints:SummingVectorOfInts.cppThis first example simply demonstrates the mechanics of manually summing up the values of integers. The final result looks quite a bit different. Before we even get there, however, let's move on to vectors with objects rather than primitives.

## Vector of Objects

Here is the same thing with a vector of objects:SummingVectorExample1.cppThis code seems barely different enough to warrant a whole example. Even so, I'm trying to show the background material you'll need to know to understand the final version. There are several steps along the way.

## Using accumulate with vector of ints

The standard library includes std::accumulate that accomplishes what we've already shown with std::for_each. Back to primitives before moving to the object:AccumulateVectorOfInts.cppHow does this work? Accumulate iterates over each element of the collection. On the first iteration it adds the "seed" value, which is 0, to the first value in the vector, which is 1. 0 + 1 -> 1, which becomes the new seed value. On the second loop, the seed value is 1, and the second value is 5. 5 + 1 -> 6, which becomes the new seed value. On the final time through the loop, the value 6 is added to the final value in the collection, 7. 6 + 7 -> 13.

In fact, the underlying algorithm uses + to add the values. The seed value is an int. The vector contains ints. The built-in + operator takes two ints and returns an int, so everything works as expected.

## Using accumulate with vectors of objects with custom operator+

Now that you've seen the basic algorithm, let's move on to a vector of objects:SummingVectorsExample2.cppThe accumulate algorithm needs a + operator that can take the seed value (an int in this case), and a value from the vector (a Value_2 object), add the results and return a value eequivalent to the seed type. That's what this function does:

This certainly works, but can we do any better than having to write a function? This seems like a common problem.

## Using accumulate with vectors of objects with conversion operator

Another option is to provide a conversion operator. Since we are doing something simple, adding ints, this happens to work:SummingVectorsExample3.cppThis works, as mentioned, because all the code is trying to sum on ints stored in an object. However, a conversion operator only works if there's only one way to get an appropriate value. If there were two int values, which would the conversion operator return? There are ways to make that work, but there's an even better way.

## Using accumulate and calling a member

This is going to be a bit of a leap. After this, there's a series of much smaller steps showing how to get to the final version.SummingVectorsExample4.cppWhat?! This is the large leap mentioned above. In a nutshell, the code passes in a function object, std::plus<int>(), that takes 2 parameters. The first parameter, being the seed (or sum), which is an int, is handled as is (_1). The second parameter is acquired by calling the instance member Value_4::getValue().

That complex expresion is a composition of function objects.

## Building up to the Complex Composition & Beyond

The final version is a huge jump from the immediately proceeding version. How can we go from one to the next?## This is Where C++0x comes into play

These next examples use type inference, one of the features in C++0x. If you followed the steps mentioned above, you'll be able to take this code as is and get it to compile. (All of the examples here come from compiling code with all of the tests passing.)## The Infrastructure

First, the top of the source file:Notice that the Value class has both getValue() and operator int(). The conversion operator (operator int()) is used in one of the examples but not the final version.)

## Calling the functor Directly

This first test demonstrates simply calling add with two arguments:This works because

std::plusoperator()std::plusInitially, theres a definition for

foobarfoobazf_pointerfoofooThe function

muchBetterstd::plusoperator()Why all of this background? Well what if I have the following template method:

This template method,

executeoperator()foocallBothstd::plus<int>operator()execute## Binding Both Parameters

Notice how the template methodexecutefoostd::plus<int>boost::bindThe call to

boost::bindSince the two parameters required by std::plus have been stored internally, executing

functor## Binding the second parameter

What if we want to bind the second parameter, but allow the first one to be provided by the caller:This accomplishes that. Note that we could use std::bind1st. I prefer boost::bind because it's more general and works well with other parts of the boost library. In this case, the object returned from bind:

Notice the call to

functor(10)## Binding no parameters

What if you want to just simply wrap thestd::plus<int>This example does that. This time, the return from

bindoperator()operator()Notice the call to

functor(10, 42)## Binding the second parameter to a method call

Now things get more complex, and realistic. Rather than calling v.getValue() directly, we'll instead provide a binding to a call to v.getValue(). The call to v.getValue() was happeningbeforeboost::bindafterduringAs before, the functor returned from

bind- Stores add
- Stores _1, which is a reference the the first parameter passed into operator()

Now, however, it also stores the result ofbind(&Value::getValue, _2)operator()This is a game-changer. Notice that rather than calling

functor(10, v.getValue())functor(10, v)operator()operator()bind(&Value::getValue, _2)operator()operator()operator()operator()bindValue::getValue, which returns 52.std::plus<int>::operator()## How you're probably write this in practice

This is how you'd probably write this in practice:## Return to

With that background, we can now return toaccumulateaccumulateThis invocation of

std::accumulateValue::operator int()std::accumulate## Back to the final solution

Here's the merging of these two results together:In practice, using a temporary is not how you'd probably write this code:

## Working with vectors of shared_ptr

Let's look at one final example. Imagine you want to have a vector of dynamically-allocated objects. Instead of storing raw pointers, you might think to use some kind of smart pointer, such asstd::auto_ptrstd::auto_pointerboost::shared_ptrThis is a place where

boost::bindstd::bind1ststd::bind2ndboost::shared_ptr## The Whole File

Each of these examples are pulled from one larger, compiling C++ source file. Here's the whole file:PlusAndBindTest.cpp<-- Back