Category Archives: C/C++

Folding expressions in C++ 17

Setup your dev tools to use C++ 17

Using CLion (or CMake) and setting the CMakeLists.txt CMAKE_CXX_STANDARD to

set(CMAKE_CXX_STANDARD 17)

allows us to use C++ 17 features.

In CLion the intellisense/editor will show folding expressions with red underlines, i.e. as errors in the current release, however the code will compile

Folding Expressions

Basically folding expressions allow us to write code which takes one or more arguments and applies operators to them to create a return value.

In C++ terms, folding expressions take variadic template arguments and unpack the arguments using unary or binary operators to create a return value.

The syntax for folding expressions, is as follows

Syntax (as taken from http://en.cppreference.com/w/cpp/language/fold).

  • unary right fold (pack op …)
  • unary left fold (… op pack)
  • binary right fold (pack op … op init)
  • binary left fold (init op … op pack)

Let’s look at some examples to make things clearer using this syntax.

Unary right fold

The following is a simple summation method using unary right fold syntax

template<typename... Args>
auto unary_right_fold(Args... args) {
    return (args + ...);
}

Unary left fold

The following is a simple summation method using unary left fold syntax

template<typename... Args>
auto unary_left_fold(Args... args) {
    return (... + args);
}

Binary right fold

The following is a simple summation + 1 method using binary left fold syntax

template<typename... Args>
auto binary_right_fold(Args... args) {
    return (args + ... + 1);
}

Binary left fold

The following is a simple 1 + summation method using binary left fold syntax

template<typename... Args>
auto binary_left_fold(Args... args) {
    return (1 + ... + args);
}

threads, promises, futures, async, C++

The only C++ application I now maintain used a single thread to handle background copying and it was fine, but anything more than that and it becomes a little more complex to maintain, especially when compared to threading in C#, such as TPL, Parallel library and async/await.

Now whilst these new features/libraries are not in the same “ease of use” area as those C# classes etc. they are nevertheless a massive step forward.

From what I can tell, we have four different multi-threaded operations (I think that’s the best way to put it). I’m not talking locking, or other forms of synchronization here.

std::thread

So at the most basic level we have the std::thread which is extremely simple to use, here’s an example

auto t = std::thread([]
{
   // do something in a thread
});

We can block (or wait) until the thread has completed using t.join();, but there’s other possibilities for interacting with our thread.

std::future and std::promise

Futures and promises are two sides of the same coin, so to speak. A promise allows us to return state from a thread. Whereas a future is for reading that returned state.

In other words, let’s think of it in this, fairly simple way – we create a promise that really says that at some time there will be a state change or return value from thread. The promise can be used to get a std::future, which is the object that gives us this return result.

So we’ve got the equivalent of a simple producer/consumer pattern

auto promise = std::promise<std::string>();
auto producer = std::thread([&]
{
   // simulate some long-ish running task
   std::this_thread::sleep_for(std::chrono::seconds(5));
   promise.set_value("Some Message");
});

auto future = promise.get_future();
auto consumer = std::thread([&]
{
   std::cout << future.get().c_str();
});

// for testing, we'll block the current thread
// until these have completed
producer.join();
consumer.join();

Note: In the example above I’m simply using a lambda and passing reference to all variables in scope via the capture, using [&], as a capture list is required to access the promise and future outside of the lambdas.

In this example code we simply create a promise and then within the first thread we’re simulating a long-ish running task with the sleep_for method. Once the task is complete we set_value on the promise which causes the future.get() to unblock, but we’ve jumped ahead of ourselves, so…

Next we get the future (get_future) from the promise and to simulate a a producer/consumer we spin up another thread to handle any return from the promise via the future.

In the consumer thread, the call to future.get() will block that thread until the promise has been fulfilled.

Finally, the code calls producer.join() and consumer.join() to block the main thread until both producer and consumer threads have completed.

std::async

The example for the promise/future combination to create a producer consumer can be simplified further using the std::async which basically deals with creating a thread and creating a future for us. So let’s see the code for the producer/consumer now with the std::async

std::future<std::string> future = std::async([&]
{
   std::this_thread::sleep_for(std::chrono::seconds(5));
   return std::string("Some Message");
});

auto consumer = std::thread([&]
{
   std::cout << future.get().c_str();
});

consumer.join();

In the above we’ve done away with the promise and the first thread which have both been replaced with the higher level construct, std::async. We’ve still got a future back and hence still call future.get() on it, but notice how we’ve also switch to returning the std::string and the future using the template argument to match the returned type.

We’re not actually sure if the code within the async lambda is run on a new thread or run on the calling thread, as the async documentation states…

“The template function async runs the function f asynchronously (potentially in a separate thread which may be part of a thread pool) and returns a std::future that will eventually hold the result of that function call.”

So the async method may run the code on a thread or deferred. Deferred meaning the code is run when we call the future’s get method in a “lazy” manner.

We can stipulate whether to run on a thread or as deferred using an std::async overload

std::future<std::string> future = 
   std::async(std::launch::deferred, [&]
   {
   });

In the above we’ve deferred the async call and hence it’ll be run on the calling thread, alternatively we could stipulate std::launch::async, see std::launch.

What about exceptions?

If an exception occurs in async method or the promise set_exception is called in our producer/consumer using a promise. Then we need to catch the exception in the future (call to get()). Hence here’s an example of the async code with an exception occuring

std::future<std::string> future = std::async([&]
{
   throw std::exception("Some Exception");
   return std::string("Some Message");
});

auto consumer = std::thread([&]
{
   try
   {
      std::cout << future.get().c_str();
   }
   catch(std::exception e)
   {
      std::cout << e.what();
   }
});

consumer.join();

Here we throw an exception in the async lambda and when future.get is called, that exception is propagated through to the consumer thread. We need to catch it here and handle it otherwise it will leak through to the application and potentially crash the application if not handled elsewhere.

Variadic template arguments in C++

We’ve had varargs forever in C/C++ but variadic templates allow us to use strongly types variadic arguments.

We’re going to create a simple container (which just wraps a vector) and then extend this with variadic template arguments

template<typename T>
class container
{
   std::vector<T> _values;
public:
};

Now we want to add a push_back method which allows us to pass in multiple values, so the code would look like this

container<int> c;
c.push_back(1, 2, 3);

If we declare a public method which looks like this

template<typename ...Args>
void push_back(Args... args)
{
}

we can see the …Args in the template, these are variadic template arguments and you can see from the push_back parameters how we might use this.

But how do we get the variables 1, 2 & 3 that were passed as arguments? Unfortunately these are not translated to an array or similar, but we can use recursion and a change in our method signature to solve this.

Here’s the code

template<typename ...Args>
void push_back(T v, Args... args)
{
   _values.push_back(v);
   push_back(args...);
}

With this the calling code c.push_back(1, 2, 3); is actually passing to the push_back method the equivalent of push_back(int, variable arguments), so the first item is assign to argument v and the 2 & 3 to to args. Now using recursion we can “unpack” the args with the call push_back(args…), however this will not compiler because at some point the variable args will be empty, i.e. there’s no push_back method which takes no arguments. So we need to add the followin

static void push_back() {}

as a private method and this acts as a recursive terminator method. i.e. called when no arguments exist and causes the recursion to complete and allows the stack to unwind.

Ofcourse an alternative to variable arguments is to use the std::initializer_list (as discussed in a previous post), so the calling code might now look like this

container<int> c;
c.push_back({ 1, 2, 3 });

From our example class, remove the push_back methods and replace with

void push_back(std::initializer_list<T> il)
{
   for(auto it = il.begin(); it != il.end(); ++it)
   {
      _values.push_back(*it);
   }
}

Obviously the variable template arguments looks a lot more natural but may not suit every use.

Note: The variadic argument templates are also used in C++ folding expressions, which I will discuss in a subsequent post.

Whilst the example container was handling a single generic type, we could (as you can see from the push_back methods) create methods that handle different types. Let’s assume we have a simple type_checker class, which outputs what each argument type is, we could write the following

class type_checker
{
   static void what() {}
public:
   template<typename ...Args>
   void what(int v, Args... args)
   {
      std::cout << "Int " << v << std::endl;
      what(args...);
   }

   template<typename ...Args>
   void what(std::string v, Args... args)
   {
      std::cout << "String " << v.c_str() << std::endl;
      what(args...);
   }
};

// calling code

type_checker c;
c.what(1, "Hello", 3);

Now we’re passing in heterogeneous data and depending upon the first argument type each time to choose the correct overload method. The variadic arguments are unpacked and again the correct overload will be called.

To understand this more clearly, the c.what(1, “Hello”, 3);
line of code in this example will call the what methods as follows.

The what(int, …) is called first followed by what(std::string, …) followed by what(int, …) and finally what().

More on initializer lists in C++

Initializer lists in C++ allow us to intialize arrays/vectors and more using a simple syntax, for example

std::vector<std::string> v = { "one", "two", "three" };

This will create a vector with three values “one”, “two” and “three”.

This works because an intializer list (i.e. the { “one”, “two”, “three” } in this example, is actually a std::initializer_list type and the vector has an overload = operator which accepts such a type and then copies the values into the vector. So the { } syntax is really just syntactic sugar.

Here’s the same code but showing the explicit use of the type, i.e. we create a std::initializer_list

std::initializer_list<int> il = { 1, 2, 3 };
// which is the same as this, with an auto
auto il = { 1, 2, 3 };

Knowing, as we do, that the initializer list will in fact create a std::initializer_list, it’s obvious that this will come with a slight overhear in terms of creating a std::initializer_list, then when assigned to a vector/array or the likes, we need to loop through the items in the list and copy into the vector. Hence if out and out speed and member use is an issue, one might prefer not to use such syntax.

We can also use an initializer list with a single value, for example

auto i{ 3 };

and this resolves to an int type with the value 3.

Pointers to functions, easier than they used to be…

For this post, I wanted to implement a callback in C++.

A method I have does some work (copying files) which might take minutes to complete and whilst copying the files it posts updates back to the callback telling the calling method of the progress, i.e. the file that’s being copied.

The code for the method which takes a callback looks like this, notice we’re using the std::function to wrap our callback

void Update(
   std::vector<UpdateInfo*>& updates, 
   std::function<void(std::tstring&, std::tstring&)> callback)
{
   // does something and then calls the following 
   callback(item->source, item->destination)
}

To create the call we use

std::function<void(std::tstring&, std::tstring&)> f = 
   std::bind(&MyClass::NotifyUpdate, 
      this, 
      std::placeholders::_1, 
      std::placeholders::_2);

Update(f);

the _1, _2 are placeholders, allowing us to alter the values from the caller at a later time (i.e. from the Update method in this case). The std::bind method allows us to wrap a function ptr and an instance of the class containing the callback (the NotifyUpdate method).

C++ lambda’s in a little more depth

Lambda expressions appeared in C++ 11.

Let’s take a simple example. We want to create a lambda which takes an enum (of type UpdateFlag) and returns a LPTSTR (yes we’re in Visual C++ world) which we’ll use when we writing to cout.

We can create the lambda like this

auto lambda = [](UpdateFlag flag)
{
   switch (flag)
   {
      case UpdateFlag::Update:
         return _T("Update");
      case UpdateFlag::Delete:
         return _T("Delete");
      case UpdateFlag::Missing:
         return _T("Missing");
   }
};

if you prefer to not use the auto keyword we can use the functional code like this

std::function<LPCTSTR(UpdateFlag)> lambda = [](UpdateFlag flag)
{
// switch removed for brevity
};

I’m not quite sure where you’d need to use the std::function variation of this, but this is what it would look like.

Now to use our lambda, we’d simply have something like

std::cout << lamba(updateFlag);

We can also pass the lambda (without creating a variable to it) using the following

std::cout << [](UpdateFlag flag)
{
// switch removed for brevity
}(updateFlag);

Note: we need to pass the updateFlag in a parameter list after the lamba declaration.

The [] is an empty capture list, we could alter the previous samples (assuming a variable updateFlag is available within the scope of the lambda) by passing the updateFlag as part of the capture list, for example

auto updateFlag = UpdateFlag::Update;

auto lambda = [updateFlag]
{
   switch (updateFlag)
   {
      case UpdateFlag::Update:
         return _T("Update");
      case UpdateFlag::Delete:
         return _T("Delete");
      case UpdateFlag::Missing:
         return _T("Missing");
   }
};

Structuring the lamba

Let’s look at the format of the lamba…

The lamba syntax basically takes the form

  • [capture-list] (params) mutable(optional) constexpr(optional)(c++17) exception attribute -> ret { body }
  • [capture-list](params) -> ret { body }
  • [capture-list](params) { body }
  • [capture-list] { body }

The above is replicated from the Lambda expressions page.

The capture-list is a comma seperated list of zero or more captures, which takes or “captures” variables to be passed into the lambda.

The params are a standard list of parameters to pass into your lambda and the body is your actual code.

References

An excellent article on the subject of C++ 11 lambda’s can be found here.
The lambda specification can be found here.

Revisiting an old friend

Reminiscing

For many years (a long time ago in a galaxy far away) I was a C++ developer, but I haven’t done much in C++ for a while now, until recently…

I needed to revisit a C++ application I wrote (not quite so long ago) to make a few additions and at the same time I thought it worth reviewing the changes that have taken place in C++ in recent years. This post is primarily looking at some of the changes as part of C++ 11 that I’ve come across whilst updating my app. and whilst not comprehensive, should give a taste for “Modern C++”.

auto is to C++ what var is to C#

auto i = 1234;

This is resolved to the type at compile time (i.e. it’s not dynamic). The compiler simply resolves the type based upon the value on the right hand side of the assignment operator.

decltype

template<typename A, typename B>
auto f(A a, B b) -> decltype(a + b)
{
	return a + b;
}

We can also use it in a sort of dynamic typedef manner

decltype(123) v = 1;
// equivalent to 
int v = 1;

decltpye(123) declares the type as an int (as the type is taken from the argument passed in) then the value 1 is assigned to the variable.

for (each) loops known as range based loops in C++

The for loop (in a similar way to Java uses it) can be used as a foreach style loop. Although C++ calls this a range based loop. It only works on arrays or objects which have begin and end member functions (or initializer lists)

for(auto &it : myvector)
{   
}

// using initializer list

for(auto i : { 1, 2, 3})
{
}

nullptr takes over from NULL

The nullptr is a strongly typed keyword which can replace those NULL or 0 usages when setting or testing a variable to see whether it points at something or not.

if(errors == nullptr) 
{
}

Another benefit of the keyword being strongly typed is that in situations when we might have two methods (with the name overloaded) one taking and int, the second a pointer type, then the compiler can now correctly choose the pointer overload, for example

void f(int i)
{
}

void f(int* i)
{
}

f(NULL);    // calls f(int i)
f(nullptr); // calls f(int* i)

So obviously the use of the NULL suggests the developer wants to use f(int*), but this is ambiguous and both could be correct. In the case of Visual Studio f(int) is called when we use NULL.

Lamda’s as well

I’ve written a longer post on lambda’s which will be published after this post. However, here’s a taster showing a lamda used within the algorithm header’s std::for_each function

std::for_each(v.begin(), v.end(), [](int i)
{
   std::cout << i;
});

In this example, v is a vector of ints.

The lambda is denoted with the [] which captures variables from the calling code (in this case nothing is captured) and the rest is probably self-explanatory, we’ve created a lambda which takes and int and uses cout to write the value to the console.

Initializer lists

Like C# we can create lists using { } syntax, for example

std::array<int, 3> a = { 1, 2, 3 };
// or using a vector
std::vector<int> v = { 1, 2, 3 };

Sadly, Visual Studio 2015 doesn’t appear to fully support this syntax and allow us to easily intialize vectors etc. but CLion does. But thankfully Visual Studio 2017 does support this fully.

Note: Visual Studio 2015 accepts using std::vector v = { 3, (1,2,3) }; where the first number is the size of the vector.

Non-static member initializers

class FileData
{
public:
   long a {0};
   long b {1};
}

Upon creation of a FileData instance, a is initialized to 0 and b is initialized to 1.

Tuples

We can now create tuples by include the tuple header and creating a tuple using the std::make_tuple function, i.e.

auto t = std::make_tuple<int, std::string>(123, "Hello");

To get at each part of the tuple we can use either the get function or the tie function, like this

std::cout 
   << std::get<0>(t) 
   << std::get<1>(t) 
   << std::endl;

Note: the index goes in the template argument.

Or using tie

int a;
std::string b;

std::tie(a, b) = t;

std::cout 
   << a 
   << b 
   << std::endl;

std::thread, yes threads made easier

Okay, we’re not talking Task or async/await capabilities like C# but the std::thread class makes C++ threading that bit easier.

#include <thread>
#include <iostream>

void f(std::string s, int n) {
   for (int i = 0; i < n; i++)
      std::cout << s.c_str() << std::endl;
}
int main()
{
   std::thread thread1(f, "Hello", 10);
   std::thread thread2(f, "World", 3);
	
   thread1.join();
   thread2.join();

    return 0;
}

In this code we create a thread passing in the function and the arguments for the function, using join to wait until both threads have completed.

References

Modern C+ Features
Support For C++11/14/17 Features (Modern C++)