Tag Archive : c++11

/ c++11

C++ is growing, as per new standard C++11 now it supports threading. C++11 introduce a new thread library. The new standard define utilities for starting and managing threads. It also contains utilities for synchronization like mutexes and other locks, atomic variables, and other utilities. We will get through this so called C++11 threading by series of articles “C++11 Concurrency”.

To compile the sample code, we need a C++11 compiler. In my case, I use GCC 4.8.1 (on Slackware Linux) or MinGW counterpart (on Windows 8.1). To activated C++11 support features, we need to pass the “-std=c++11″ option to GCC, for example:

g++ filename.cpp -o program -std=c++11

C++ Concurrency

see <atomic>, <condition_variable>, <future>, <mutex>, and <thread> for reference.

Starting from C++11, there are five more headers added to the standard library to support concurrency. They are:

  • atomic
  • condition_variable
  • future
  • mutex
  • thread

These headers are used for multithreading and concurrency. Before the language standard, we would use OS facilities such as POSIX thread or libraries like OpenMP and MPI to enable concurrency using C++.

The <atomic> header defines some definition to allow us using atomic operation. It encapsulate a value whose access is guaranteed to not cause data races and can be used to synchronize memory access among different threads.

The <condition_variable> header defines classes used as condition variable for synchronization.

The <future> header facilitates synchronization access to value.

The <mutex> header is used for allowing mutual exclusion (mutex) of concurrent execution of critical sections of code.

The <thread> header defines thread class, used for spawning threads on C++ and also manage threads as we like.

Starting Threads

see also: Multithreading Support in C++11

Starting a new thread is very easy. We need to create an instance of a std::thread and supply a function and thread will automatically be started and executing the function. The function we talk about can be a function pointer or even a lambda expression.

So first, let’s write a simple code to demonstrate the power of C++ thread.

#include <thread>  
#include <iostream>    
using std::cout;  
using std::endl;  
using std::thread;    
void hello(){
   cout << "Hello from thread " << endl;
}    

int main(){      
   thread t1(hello);   
   t1.join();    
 
   return 0;  
}

In the above snippet, we pass a function pointer to thread.

All the threads utilities can be found in the <thread> header. As we see, when constructing a thread instance, we supply a function which will be executed on the fly. The join() method is called to force current thread to wait for the other one. In other word, main thread won’t finish until t1 finish it’s task. If we omit this call, the result is undefined.

We can, however, create more than one thread. To distinguish each of thread, the std::thread class provide a get_id() method which returns an unique id for this thread. We can get a reference to the current thread by std::this_thread variable. Let’s dive in example:

#include <thread>  
#include <iostream>  
#include <vector>    
using std::cout;  
using std::endl; 
using std::thread;  
using std::vector;    

void hello(){      
   cout << "Hello from thread " << this_thread::get_id() << endl;  
}    

int main(){   
   vector<thread> threads;      
   for (int i = 0; i < 5; ++i) { 
      threads.push_back(thread(hello));      
   }        
   for (auto& thread : threads){       
      thread.join();      
   }        

   return 0;  
}

Sample output:

Hello from thread 2  
Hello from thread 4  
Hello from thread 3  
Hello from thread 5  
Hello from thread 6

Our program will start thread one after one and then store them into a vector. This is common strategy to handle several threads.

The threads might interleave. We have no way to control the order of execution of threads. A thread can be preempted at any moment which might lead us to produce following result:

Hello from thread 
Hello from thread 6  
Hello from thread 3  
Hello from thread 5  
2 
Hello from thread 4

So, there is no certainty in which function will be executed first. All decision are taken by OS. The Operating System will decide when resource are available for our threads and execute them on whatever CPU is least occupied.

Aside from function pointer, we can also use lambda expression. Lambda execution is very useful when the executing code is very small thus we don’t necessary need to create a function just for that. We can rewrite the previous code as this one:

#include <thread>  
#include <iostream>  
#include <vector>    
using std::cout;  
using std::endl;  
using std::thread;  
using std::vector;    

int main(){      
   vector<thread> threads;        
   for (int i = 0; i < 5; ++i){          
      threads.push_back(thread([]() {
         cout << "Hello from thread " << this_thread::get_id() << endl; 
      }));
   }
   for (auto& thread : threads){
      thread.join();
   }
   return 0;
}

Threading in Action

Now we will illustrate the power of parallel programming in C++11. We will do something simple yet interesting: parallel merge sort.

Ten C++11 Features You Should Know and Use

December 11, 2015 | Article | No Comments

This article will be a resume to several articles discussing individual subject.

There are lots of new additions to the C++ language and standard library after C++11 standard passed. However, I believe some of these new features should become routing for all C++ developers.

Features we are talking about:

  1. auto & decltype
  2. nullptr
  3. Range-based for loops
  4. Override and final
  5. Strongly-typed enums
  6. Smart pointers
  7. Lambdas
  8. non-member begin() and end()
  9. static_assert and type traits
  10. Move semantics

auto & decltype

More: Improved Typed Reference in C++11: auto, decltype, and new function declaration syntax

Before C++11 era, keyword auto was used for storage duration specification. In the new standard, C++ define clearly the purpose to be type inference. Keyword auto is a placeholder for a type, telling the compiler it has to deduce the actual type of a variable that is being declared from its initializer.

auto I = 42;        // I is an int
auto J = 42LL;      // J is an long long
auto P = new foo(); // P is a foo* (pointer to foo)

Using auto means less code for writing typename. The very convenience use of auto would be inferring type for iterator:

std::map<std::string, std::vector<int>> myMap;
for (auto it = begin(map); it != end(map); ++it)
{
//...
}

Here we save lot of works by order compiler to deduce the type of it.

decltype in other hand is a handy keyword to get type of an expression. Here we can inspect what’s going on this code:

short a = 10;
long b = 655351334;
decltype(a+b) c = 5;

std::cout << sizeof(a) << " " << sizeof(b) << " " << sizeof(c) << std::endl;

When we execute this code using proper C++11 compiler, we got variable c as a type used for summation of a and b. We know that when a short is summed with a long, the short variable will be typecasted automatically to type sufficient enough to hold the result code. And the decltype will give us it’s type.

As said before, decltype is used to get type of an expression, therefore it is valid for use to do this:

int function(int a, int b)
{
	return a * b;
}

int main()
{
	decltype(function(a,b)) c = 10;

	return 0;
}

As long as the expression involved is valid.

Now, in C++ we have a new function declaration syntax. This syntax leverage the power of both auto and decltype. Note that auto cannot be used as the return type of a function, so we must have a trailing return type. In this case auto does not tell the compiler it has to infer the type, it only instructs it to look for the return type at the end of the function.

template <typename T1, typename T2>
auto compose(T1 t1, T2 t2) -> decltype (t1 + t2)
{
	return t1+t2;
}

In above snippet, we compose the return type of function from the type of operator + that sums the values of types T1 and T2.

nullptr

More: Nullptr, Strongly typed Enumerations, and Cstdint

Since the inception of C++, zero is used as the value of null pointers. This is a direct influence from C language. The system itself has drawbacks due to the implicit conversion to integral types.

void function(int a);
void function(void* a);

function(NULL);

Now, which one is being called? On smarter compiler, it will gives error saying “the call is ambiguous”.

C++11 library gives solution for this. Keyword nullptr denotes a value of type std::nullptr_t that represents the null pointer literal. Implicit conversions exists from nullptr to null pointer value of any pointer type and any pointer-to-member types, but also to bool (as false). But no implicit conversion to integral types exists.

void foo(int* p) {}

void bar(std::shared_ptr<int> p) {}

int* p1 = NULL;
int* p2 = nullptr;   
if(p1 == p2)
{
}

foo(nullptr);
bar(nullptr);

bool f = nullptr;
int i = nullptr; // error: A native nullptr can only be converted to bool or, using reinterpret_cast, to an integral type

Using 0 is still valid for backward compatibility.

Range-based for loops

More: C++ Ranged Based Loop

Ever wonder how could we do foreach statement in C++? Joy for us because C++11 now augmented the for statement to support it. Using this foreach paradigm we can iterate over collections. In the new form, it is possible to iterate over C-like arrays, initializer lists, and anything for which the non-member begin() and end() functions are overloaded.

std::map<std::string, std::vector<int>> map;
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
map["one"] = v;

for(const auto& kvp : map) 
{
  std::cout << kvp.first << std::endl;

  for(auto v : kvp.second)
  {
     std::cout << v << std::endl;
  }
}

int arr[] = {1,2,3,4,5};
for(int& e : arr) 
{
  e = e*e;
}

The syntax is not different from “normal” for statement, okay it is a little different.

The for syntax in this paradigm is:

for (type iterateVariable : collection)
{
// ...
}

Override and final

In C++, there isn’t a mandatory mechanism to mark virtual methods as overriden in derived class. The virtual keyword is optional and that makes reading code a bit harder, because we may have to look through the top of the hierarchy to check if the method is virtual.

class Base 
{
public:
   virtual void f(float);
};

class Derived : public Base
{
public:
   virtual void f(int);
};

Derived::f is supposed to override Base::f. However, the signature differ, one takes a float, one takes an int, therefor Base::f is just another method with the same name (and overload) and not an override. We may call f() through a pointer to B and expect to print D::f, but it’s printing B::f.

C++11 provides syntax to solve this problem.

class Base 
{
public:
   virtual void f(float);
};

class Derived : public Base
{
public:
   virtual void f(int) override;
};

Keyword override force the compiler to check the base class(es) to see if there is a virtual function with this exact signature. When we compile this code, it will triggers a compile error because the function supposed to override the base class has different signature.

On the other hand if you want to make a method impossible to override any more (down the hierarchy) mark it as final. That can be in the base class, or any derived class. If it’s in a derived class, we can use both the override and final specifiers.

class Base 
{
public:
   virtual void f(float);
};

class Derived : public Base
{
public:
   virtual void f(int) override final;
};

class F : public Derived
{
public:
   virtual void f(int) override;
}

Function declared as ‘final’ cannot be overridden by ‘F::f’.

Strongly-typed enums

More: Nullptr, Strongly typed Enumerations, and Cstdint

Traditional enums in C++ have some drawbacks: they export their enumerators in the surrounding scope (which can lead to name collisions, if two different enums in the same have scope define enumerators with the same name), they are implicitly converted to integral types and cannot have a user-specified underlying type.

C++11 introduces a new category of enums, called strongly-typed enums. They are specified with the “enum class” keyword which won’t export their enumerators in the surrounding scope and no longer implicitly converted to integral types. Thus we can have a user specified underlying type.

enum class Options { None, One, All };
Options o = Options::All;

Smart pointers

All the pointers are declared in header <memory>

In this article we will only mention smart pointers with reference counting and auto releasing of owned memory that are available:

  • unique_ptr: should be used when ownership of a memory resource does not have to be shared (it doesn’t have a copy constructor), but it can be transferred to another unique_ptr (move constructor exists).
  • shared_ptr: should be used when ownership of a memory resource should be shared (hence the name).
  • weak_ptr: holds a reference to an object managed by a shared_ptr, but does not contribute to the reference count; it is used to break dependency cycles (think of a tree where the parent holds an owning reference (shared_ptr) to its children, but the children also must hold a reference to the parent; if this second reference was also an owning one, a cycle would be created and no object would ever be released).

The library type auto_ptr is now obsolete and should no longer be used.

The first example below shows unique_ptr usage. If we want to transfer ownership of an object to another unique_ptr use std::move. After the ownership transfer, the smart pointer that ceded the ownership becomes null and get() returns nullptr.

void foo(int* p)
{
   std::cout << *p << std::endl;
}
std::unique_ptr<int> p1(new int(42));
std::unique_ptr<int> p2 = std::move(p1); // transfer ownership

if(p1)
  foo(p1.get());

(*p2)++;

if(p2)
  foo(p2.get());

The second example shows shared_ptr. Usage is similar, though the semantics are different since ownership is shared.

void foo(int* p)
{
   std::cout << *p << std::endl;
}
void bar(std::shared_ptr<int> p)
{
   ++(*p);
}
std::shared_ptr<int> p1(new int(42));
std::shared_ptr<int> p2 = p1;

foo(p2.get());
bar(p1);   
foo(p2.get());

We can also make equivalent expression for first declaration as:

auto p3 = std::make_shared<int>(42);

make_shared<T> is a non-member function and has the advantage of allocating memory for the shared object and the smart pointer with a single allocation, as opposed to the explicit construction of a shared_ptr via the contructor, that requires at least two allocations. In addition to possible overhead, there can be situations where memory leaks can occur because of that. In the next example memory leaks could occur if seed() throws an error.

void foo(std::shared_ptr<int> p, int init)
{
   *p = init;
}
foo(std::shared_ptr<int>(new int(42)), seed());

No such problem exists if using make_shared.

The last sample shows usage of weak_ptr. Notice that you always must get a shared_ptr to the referred object by calling lock(), in order to access the object.

auto p = std::make_shared<int>(42);
std::weak_ptr<int> wp = p;

{
  auto sp = wp.lock();
  std::cout << *sp << std::endl;
}

p.reset();

if(wp.expired())
  std::cout << "expired" << std::endl;

Lambdas

More: Guide to Lambda Closure in C++11

Lambda is anonymous function. It is powerful feature borrowed from functional programming that in turned enabled other features or powered library. We can use lambda wherever a function object or a functor or a std::function is expected.

You can read the expression here.

std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);

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

auto is_odd = [](int n) {return n%2==1;};
auto pos = std::find_if(std::begin(v), std::end(v), is_odd);
if(pos != std::end(v))
  std::cout << *pos << std::endl;

A bit trickier are recursive lambdas. Imagine a lambda that represents a Fibonacci function. If you attempt to write it using auto you get compilation error:

auto fib = [&fib](int n) {return n < 2 ? 1 : fib(n-1) + fib(n-2);};

The problem is auto means the type of the object is inferred from its initializer, yet the initializer contains a reference to it, therefore needs to know its type. This is a cyclic problem. The key is to break this dependency cycle and explicitly specify the function’s type using std::function.

std::function<int(int)> lfib = [&lfib](int n) {return n < 2 ? 1 : lfib(n-1) + lfib(n-2);};

non-member begin() and end()

Two new addition to standard library, begin() and end(), gives new flexibility. It is promoting uniformity, concistency, and enabling more generic programming which work with all STL containers. These two functions are overloadable, can be extended to work with any type including C-like arrays.

Let’s take an example. We want to print first odd element on a C-like array.

int arr[] = {1,2,3};
std::for_each(&arr[0], &arr[0]+sizeof(arr)/sizeof(arr[0]), [](int n) {std::cout << n << std::endl;});

auto is_odd = [](int n) {return n%2==1;};
auto begin = &arr[0];
auto end = &arr[0]+sizeof(arr)/sizeof(arr[0]);
auto pos = std::find_if(begin, end, is_odd);
if(pos != end)
  std::cout << *pos << std::endl;

With non-member begin() and end() it could be put as this:

int arr[] = {1,2,3};
std::for_each(std::begin(arr), std::end(arr), [](int n) {std::cout << n << std::endl;});

auto is_odd = [](int n) {return n%2==1;};
auto pos = std::find_if(std::begin(arr), std::end(arr), is_odd);
if(pos != std::end(arr))
  std::cout << *pos << std::endl;

This is basically identical code to the std::vector version. That means we can write a single generic method for all types supported by begin() and end().

template <typename Iterator>
void bar(Iterator begin, Iterator end) 
{
   std::for_each(begin, end, [](int n) {std::cout << n << std::endl;});

   auto is_odd = [](int n) {return n%2==1;};
   auto pos = std::find_if(begin, end, is_odd);
   if(pos != end)
      std::cout << *pos << std::endl;
}

template <typename C>
void foo(C c)
{
   bar(std::begin(c), std::end(c));
}

template <typename T, size_t N>
void foo(T(&arr)[N])
{
   bar(std::begin(arr), std::end(arr));
}

int arr[] = {1,2,3};
foo(arr);

std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
foo(v);

static_assert and type traits

static_assert performs an assertion check at compile-time. If the assertion is true, nothing happens. If the assertion is false, the compiler displays the specified error message.

template <typename T, size_t Size>
class Vector
{
   static_assert(Size < 3, "Size is too small");
   T _points[Size];
};

int main()
{
   Vector<int, 16> a1;
   Vector<double, 2> a2;
   return 0;
}

static_assert becomes more useful when used together with type traits. These are a series of classes that provide information about types at compile time. They are available in the <type_traits> header. There are several categories of classes in this header: helper classes, for creating compile-time constants, type traits classes, to get type information at compile time, and type transformation classes, for getting new types by applying transformation on existing types.

In the following example function add is supposed to work only with integral types.

template <typename T1, typename T2>
auto add(T1 t1, T2 t2) -> decltype(t1 + t2)
{
   return t1 + t2;
}

However, there are no compiler errors if one writes

std::cout << add(1, 3.14) << std::endl;
std::cout << add("one", 2) << std::endl;

The program actually prints 4.14 and “e”. But if we add some compile-time asserts, both these lines would generate compiler errors.

template <typename T1, typename T2>
auto add(T1 t1, T2 t2) -> decltype(t1 + t2)
{
   static_assert(std::is_integral<T1>::value, "Type T1 must be integral");
   static_assert(std::is_integral<T2>::value, "Type T2 must be integral");

   return t1 + t2;
}

Move semantics

More: Move Semantics and rvalue references in C++11

C++11 has introduced the concept of rvalue references (specified with &&) to differentiate a reference to an lvalue or an rvalue. An lvalue is an object that has a name, while an rvalue is an object that does not have a name (temporary object). The move semantics allow modifying rvalues (previously considered immutable and indistinguishable from const& types).

A C++ class/struct used to have some implicit member functions: default constructor (only if another constructor is not explicitly defined) and copy constructor, a destructor and a copy assignment operator. The copy constructor and the copy assignment operator perform a bit-wise (or shallow) copy, i.e. copying the variables bitwise. That means if you have a class that contains pointers to some objects, they just copy the value of the pointers and not the objects they point to. This might be OK in some cases, but for many cases you actually want a deep-copy, meaning that you want to copy the objects pointers refer to, and not the values of the pointers. In this case you have to explicitly write copy constructor and copy assignment operator to perform a deep-copy.

What if the object you initialize or copy from is an rvalue (a temporary). You still have to copy its value, but soon after the rvalue goes away. That means an overhead of operations, including allocations and memory copying that after all, should not be necessary.

Enter the move constructor and move assignment operator. These two special functions take a T&& argument, which is an rvalue. Knowing that fact, they can modify the object, such as “stealing” the objects their pointers refer to. For instance, a container implementation (such as a vector or a queue) may have a pointer to an array of elements. When an object is instantiating from a temporary, instead of allocating another array, copying the values from the temporary, and then deleting the memory from the temporary when that is destroyed, we just copy the value of the pointer that refers to the allocated array, thus saving an allocation, copying a sequence of elements, and a later deallocation.

The following example shows a dummy buffer implementation. The buffer is identified by a name (just for the sake of showing a point revealed below), has a pointer (wrapper in an std::unique_ptr) to an array of elements of type T and variable that tells the size of the array.

template <typename T>
class Buffer 
{
   std::string          _name;
   size_t               _size;
   std::unique_ptr<T[]> _buffer;

public:
   // default constructor
   Buffer():
      _size(16),
      _buffer(new T[16])
   {}

   // constructor
   Buffer(const std::string& name, size_t size):
      _name(name),
      _size(size),
      _buffer(new T[size])
   {}

   // copy constructor
   Buffer(const Buffer& copy):
      _name(copy._name),
      _size(copy._size),
      _buffer(new T[copy._size])
   {
      T* source = copy._buffer.get();
      T* dest = _buffer.get();
      std::copy(source, source + copy._size, dest);
   }

   // copy assignment operator
   Buffer& operator=(const Buffer& copy)
   {
      if(this != &copy)
      {
         _name = copy._name;

         if(_size != copy._size)
         {
            _buffer = nullptr;
            _size = copy._size;
            _buffer = _size > 0 > new T[_size] : nullptr;
         }

         T* source = copy._buffer.get();
         T* dest = _buffer.get();
         std::copy(source, source + copy._size, dest);
      }

      return *this;
   }

   // move constructor
   Buffer(Buffer&& temp):
      _name(std::move(temp._name)),
      _size(temp._size),
      _buffer(std::move(temp._buffer))
   {
      temp._buffer = nullptr;
      temp._size = 0;
   }

   // move assignment operator
   Buffer& operator=(Buffer&& temp)
   {
      assert(this != &temp); // assert if this is not a temporary

      _buffer = nullptr;
      _size = temp._size;
      _buffer = std::move(temp._buffer);

      _name = std::move(temp._name);

      temp._buffer = nullptr;
      temp._size = 0;

      return *this;
   }
};

template <typename T>
Buffer<T> getBuffer(const std::string& name) 
{
   Buffer<T> b(name, 128);
   return b;
}
int main()
{
   Buffer<int> b1;
   Buffer<int> b2("buf2", 64);
   Buffer<int> b3 = b2;
   Buffer<int> b4 = getBuffer<int>("buf4");
   b1 = getBuffer<int>("buf5");
   return 0;
}

The default copy constructor and copy assignment operator should look familiar. What’s new to C++11 is the move constructor and move assignment operator, implemented in the spirit of the aforementioned move semantics. If you run this code you’ll see that when b4 is constructed, the move constructor is called. Also, when b1 is assigned a value, the move assignment operator is called. The reason is the value returned by getBuffer() is a temporary, i.e. an rvalue.

You probably noticed the use of std::move in the move constructor, when initializing the name variable and the pointer to the buffer. The name is actually a string, and std::string also implements move semantics. Same for the std::unique_ptr. However, if we just said _name(temp._name) the copy constructor would have been called. For _buffer that would not have been even possible because std::unique_ptr does not have a copy constructor. But why wasn’t the move constructor for std::string called in this case? Because even if the object the move constructor for Buffer is called with is an rvalue, inside the constructor it is actually an lvalue. Why? Because it has a name, “temp” and a named object is an lvalue. To make it again an rvalue (and be able to invoke the appropriate move constructor) one must use std::move. This function just turns an lvalue reference into an rvalue reference.

An alternative implementation:

template <typename T>
class Buffer
{
   std::string          _name;
   size_t               _size;
   std::unique_ptr<T[]> _buffer;

public:
   // constructor
   Buffer(const std::string& name = "", size_t size = 16):
      _name(name),
      _size(size),
      _buffer(size? new T[size] : nullptr)
   {}

   // copy constructor
   Buffer(const Buffer& copy):
      _name(copy._name),
      _size(copy._size),
      _buffer(copy._size? new T[copy._size] : nullptr)
   {
      T* source = copy._buffer.get();
      T* dest = _buffer.get();
      std::copy(source, source + copy._size, dest);
   }

   // copy assignment operator
   Buffer& operator=(Buffer copy)
   {
       swap(*this, copy);
       return *this;
   }

   // move constructor
   Buffer(Buffer&& temp):Buffer()
   {
      swap(*this, temp);
   }

   friend void swap(Buffer& first, Buffer& second) noexcept
   {
       using std::swap;
       swap(first._name  , second._name);
       swap(first._size  , second._size);
       swap(first._buffer, second._buffer);
   }
};

Perfect Forwarding in C++11

December 5, 2015 | Article | No Comments

C++11 offers a great new features called Perfect Forwarding, which is enabled via the use of rvalue references.

Perfect forwarding allows a function template to pass its arguments through to another function while retaining the original lvalue / rvalue nature of the function arguments. It avoids unnecessary copying and avoids the programmer having to write multiple overloads for different combinations of lvalue and rvalue references. A class can use perfect forwarding with variadic templates to “export” all possible constructors of a member object at the parent’s level.

class Blob
{
  std::vector<std::string> _v;
public:
  template<typename... Args>
  Blob(Args&&... args)
   : _v(std::forward<Args>(args)...)
  {  }
};
int main(void)
{
  const char * shapes[3] = { "Circle", "Triangle", "Square" };
  Blob b1(5, "C++ Truths");
  Blob b2(shapes, shapes+3);
}

The Blob class above contains a std::vector, which has many different constructors. Using a perfect forwarding constructor, the Blob class allows its clients to pass variable number of parameters that different constructors of std::vector would use. For example, object b1 uses std::vector’s constructor that takes a count and an initial value where as object b2 uses the constructor that takes an iterator pair. Also note that std::forward allows us to perfect-forward the parameters.

If you look carefully, actually this example does not require perfect forwarding as Blob constructor could take a std::vector by value and move it into the member vector object. Well, suppose we don’t know.

In practice, however, we would encounter classes that would have several members. Naturally, we may want to “export” their different constructors at its parent’s level. This is particularly true if object construction is heavy and does not support efficient move. The motivation behind this is no different than that of the emplace operations on containers. Just like the standard emplace operations, our perfect forwarding constructor allows us to construct an object in-place. We don’t even pay the cost of a move (which is often negligible for types such as std::vector). An interesting problem arises when we want to perfect forward arguments to more than one constructor. How do we decide which parameters are for which object?

Let see example below. The following Blob class has a vector of strings and a list of doubles. How do we group the parameters to the respective constructors? How do we know the programmer’s intent?

class Blob
{
  std::vector<std::string> _v;
  std::list<double> _l;
public:
  template<typename... Args>
  Blob(Args&&... args)
   : _v(???)
     _l(???)
  {  }
};
int main(void)
{
   Blob b3(5, 10, 10.0); // Three parameters and two constructors. How do we group?
}

Fortunately there is a way out and a very interesting one.

First of all, we’ve to group the parameters. An obvious candidate comes to mind: std::tuple! We could ask programmers to group the parameters in a sequence of tuples and each parameter grouped in the tuples are passed to the respective constructors.

Blob b3(std::make_tuple(5), std::make_tuple(10, 99.99));
The intent of the programmer is pretty clear in the above groupings. The vector will have 5 empty strings and the list will have 10 doubles each initialized to value = 99.99. However, we’ve a new problem now. std::vector and std::list do not accept std::tuple as parameters. We’ve to ungroup them before calling their constructors. This is far from trivial but it also makes the whole thing very interesting.

Note that retrieving values from a std::tuple requires calling std::get<i> where i is a compile-time constant that varies from 0 to the tuple_length-1. Somehow, we’ve to call std::get on each tuple with increasing values of i. To do that, we’ve to create a compile-time list of tuple indices. Here is a way to do it.

template<unsigned...> struct index_tuple{};
template<unsigned I, typename IndexTuple, typename... Types>
struct make_indices_impl;
template<unsigned I, unsigned... Indices, typename T, typename... Types>
struct make_indices_impl<I, index_tuple<Indices...>, T, Types...>
{
  typedef typename
    make_indices_impl<I + 1,
                      index_tuple<Indices..., I>,
                      Types...>::type type;
};
template<unsigned I, unsigned... Indices>
struct make_indices_impl<I, index_tuple<Indices...> >
{
  typedef index_tuple<Indices...> type;
};
template<typename... Types>
struct make_indices
  : make_indices_impl<0, index_tuple<>, Types...>
{};

make_indices is a collection of recursive meta-fuctions that compute a list of indices given a tuple type. For example, if you have (42, true, 1.2), which is tuple<int, bool, double>, make_indices<int,bool,double>::type gives index_tuple<0, 1, 2>. Here is how to use make_indices in a simple program.

template <unsigned... Indices, class... Args, class Ret>
Ret forward_impl(index_tuple<Indices...>,
                 std::tuple<Args...> tuple,
                 Ret (*fptr) (Args...))
{
  return fptr(std::get<Indices>(tuple)...);
}
template<class... Args, class Ret>
Ret forward(std::tuple<Args...> tuple, Ret (*fptr) (Args...))
{
   typedef typename make_indices<Args...>::type Indices;
   return forward_impl(Indices(), tuple, fptr);
}
int myfunc(int i, bool, double)
{
  return 5 + i;
}
int main()
{
  std::cout << forward(std::make_tuple(42, true, 1.2), myfunc) << std::endl;
}

Line #6 above is the place where the actual function is called where the list of indices and the tuple come together and two parameter packs are expanded in lockstep to yield the complete list of parameters. Note that we’re not using perfect forwarding in this case. Moreover, tuple is also copied by value. That’s fine for scalar builtin types like int, bool, and double. For large types, however, unnecessary copies may be created. The above program is simplified for the purpose of illustration.

Back to class Blob

The make_indices utility is pretty clever. But we’re not done yet. We’ve to achieve the same effect while calling the member constructors from the initialization list. We’ve to compute two lists of indices (one for vector and one for list) and expand them with the respective tuples. The question is how do we compute the list of indices before calling member constructors?

Delegated constructors come to rescue!

class Blob
{
  std::vector<std::string> _v;
  std::list<double> _l;
public:
  template <typename... Args1,
            typename... Args2>
  Blob(std::tuple<Args1...> tuple1,
       std::tuple<Args2...> tuple2)
  : Blob(tuple1,
         tuple2,
         typename make_indices<Args1...>::type(),
         typename make_indices<Args2...>::type())
  {}
private:
  template <typename... Args1,
            typename... Args2,
            unsigned... Indices1,
            unsigned... Indices2>
  Blob(std::tuple<Args1...> tuple1,
       std::tuple<Args2...> tuple2,
       index_tuple<Indices1...>,
       index_tuple<Indices2...>)
    : _v(std::forward<Args1>(std::get<Indices1>(tuple1))...),
      _l(std::forward<Args2>(std::get<Indices2>(tuple2))...)
  { }
};

The new Blob class has a public constructor that delegates to a private constructor that expects not only the tuples but also the list of indices. The private constructor is not only templatized on the tuple arguments but also on the list of indices. Once we’ve the tuples and lists of indices together, passing them to the member constructors is pretty straight forward. We simply expand the two variadic lists in unison.

Astute readers will likely notice that the Blob class is no longer using perfect forwarding because it accepts two tuples by value as opposed to an argument list in a perfect forwarding fashion shown at the beginning. That’s is on purpose. And it is not any less efficient either! Even for large types! How’s that possible?

Well, who says copying a tuple by value means copying its original parameters by value? C++ standard library provides a very convenient helper called forward_as_tuple, which perfect-forwards its parameters types as tuple members. It constructs a tuple object with rvalue references to the elements in arguments suitable to be forwarded as argument to a function. That is, the tuple member types are T&& and copying references is blazing fast. So we can afford to pass the tuples by value. Alternatively, we could use rvalue references to the tuples because in this case they are always (!) created by calling std::forward_as_tuple, which returns a temporary tuple. Here is how we use our final Blob class.

int main(void)
{
  Blob b3(std::forward_as_tuple(5, "C++ Truths"),
          std::forward_as_tuple(10, 99.99));
  // b3._v has 5 strings initialized to "C++ Truths" and
  // b3._l has 10 doubles initialized to 99.99
  Blob b4(std::forward_as_tuple(5),
          std::forward_as_tuple(10, 99.99));
  // b4._v has 5 empty strings and
  // b4._l has 10 doubles initialized to 99.99
  Blob b5(std::forward_as_tuple(),
          std::forward_as_tuple(10, 99.99));
  // b5._v is an empty vector
  // b5._l has 10 doubles initialized to 99.99
}

Using std::piecewise_construct

The Blob class looks fine and dandy so far. But the use of forward_as_tuple looks somewhat weird and does not say what it is for: in-place construction of a Blob object from its pieces. So in the final installment of the Blob class, we say what we mean. We just decorate the class with a standard (!) dummy class called std::piecewise_construct_t. The public constructor of the Blob is modified like below. We use std::piecewise_construct, a predefined object of std::piecewise_construct_t, at the call site where we create Blob objects.

#include <utility>
// ...
  template <typename... Args1,
            typename... Args2>
  Blob(std::piecewise_construct_t,
       std::tuple<Args1...> tuple1,
       std::tuple<Args2...> tuple2)
  : Blob(tuple1,
         tuple2,
         typename make_indices<Args1...>::type(),
         typename make_indices<Args2...>::type())
  {}
//...
Blob b3(std::piecewise_construct,
        std::forward_as_tuple(5, "C++ Truths"),
        std::forward_as_tuple(10, 99.99));

Obviously, the C++ library working group anticipated such situations. But are there use cases in the standard library that require the piecewise_construct idiom? As it turns out, the std::map and std::unordered_map face a very similar issue while using emplace operations. Note that std::map and std::underorder_map use a std::pair as their value_type. The pair’s .first and .second members must be constructed from a list of perfectly forwarded parameters. Obviously, the question arises what parameters go where. To solve this issue, the parameters of each member’s constructor must be wrapped as a tuple and indicate so using std::piecewise_construct so that the right pair constructor can be invoked.

C++11 New Feature: Variadic Template

December 5, 2015 | Article | 1 Comment

Before the possibilities of the new C++ language standard, C++11, the use of templates was quite limited when it campe to implementing for instance function objects (functors) & tuple facilities. Implementing these sort of things using earlier C++ standard often require similar codes to be repeated various times without forgetting preprocessor metaprogramming. However, using variadic templates, new features of C++11, make programming using templates easier, cleaner, & more memory-efficient.

In this article we will discuss about Variadic Template on C++11. I assume that you have understood what class & function templates are and how to declare, define, and use them.

What is Variadic Template?

Variadic template is a template, which can take an arbitrary number of template arguments of any type. Both the classes & funcitons can be variadic. Example can be seen below:

template<typename... Arguments>
class VariadicTemplate;

Any of the following ways to create an instance of this class template is valid:

VariadicTemplate<double, float> instance;
class VariadicTemplate;
VariadicTemplate<bool, unsigned short int, long> instance;
VariadicTemplate<char, std::vector<int>, std::string, std::string, std::vector<long long>> instance;

The number of variadic template arguments can also be zero, which mean that following also valid

VariadicTemplate<> instance;

However, a template like this:

template<typename T, typename... Argument>
class VariadicTemplate;

Must be supplied by at least one type as a template argument (which is for typename T), unless default type has been initialized, like in in the following declaration:

template<typename T = int, typename... Argument>
class VariadicTemplate;

Ellipsis Operator

Ellipsis operator (…) is an operator used in different context in C++. It;s name comes from an ellipsis mechanism in C. In this mechanism programmer can create a funciton taking variable number of parameters. Probably the most famous function in both C & C++ to take advantace of this mechanism is printf and scanf function from C standard library.

printf(const char* format, ...);
scanf(const char* format, ...);

Ellipsis mechanism can also be used with preprocessor in a form of a macro. A macro take a variable number of parameters is called a variadic macro.

#define VARIADIC_MACRO(...)

In C++, the ellipsis operator got a new meaning in different context called exception handling. The operator is used in catch blocks after try blocks which can be seen as following:

try {
   // try block
} catch (...) {
   // catch block
}

Which “catch” any exception thrown by try block and then executes the code on catch block. Thus any exception regardless of types will be taken as if parameter of function.

Later on C++11, variadic templates has brought yet another meaning for this operator. The operator works somewhat like in ellipsis mechanism with more complex. As seen at this snippet:

template<typename... Arguments>
void SampleFunction(Arguments... parameters);

The content of the variadic template arguments are called parameter packs. These packs will then be unpacked inside of function parameters. For example:  If we create a function call to previous variadic template

SampleFunction<int, int>(16,24);

then an equivalent template would be:

template<typename T, typename U>
void SampleFunction(T param1, U param2);

“Sizeof…” Operator

Another operator used with variadic templates is the sizeof… operator (yes it is sizeof followed by three dot). Unlike sizeof operator which can determine the size of a type such as sizeof(int) or sizeof(double), sizeof… operator can be used to determine the amount of types given into a variadic template. A snippet below will demonstrate:

template<typename... Arguments>
class VariadicTemplate {
  static const unsigned short int size = sizeof...(Arguments);
}
void SampleFunction(T param1, U param2);

Two Ellipsis together? (……)

In some circumtances, there can be two ellipsis operators put together (……) and yes there are six dot there which also can be separated (written as … …) Probably the most clear way, however, is to separate those two operators witha comma (such as …,…) is still acceptable.

This kind of syntax can appear with variadic function templates using ellipsis mechanism:

template<typename... Arguments>
void SampleFunction(Arguments..., ...);

Inheritance and Initialization List

When it comes to classes, variadic templates can be used with inheritance & initialization lists. Inheritance taking advantage of variadic templates can be accomplished like this:

template<typename... BaseClasses>
class VariadicTemplate : public BaseClasses...

And if we want to create a constructor inside this class using initialization list to call the constructor of all the given base classes as template arguments, we would have to do it this way:

template<typename... BaseClasses>
class VariadicTemplate : public BaseClasses... {
  VariadicTemplate(BaseClasses&&... base_classes) : BaseClasses(base_classes)... {

  }
};

Variadic Class Template Specialization

Like class templates, variadic class templates can also be specialized. With template, the specialization happens like this:

template<typename T>
class Template {
public:
  void SampleFunction(T param) {

  }
};
template<>
class Template<int> {
public:
  void SampleFunction(int param) {

  }
};

But with variadic templates it become like this:

template<typename... Arguments>
  class VariadicTemplate {
public:
  void SampleFunction(Arguments... param) {

  }
};

template<>
  class VariadicTemplate<double, int, long> {
public:
  void SampleFunction(double param1, int param2, long param3) {

  }
};

Conclusion

Templates have been a powerful feature in C++. Now, after the introduction of variadic template, templates have proven themselves even more powerful. Variadic templates are a trusworthy solution to implement delegates and tuples. And, instead of C-style ellipsis mechanism, variadic templates can offer a typesafer solution to replace them.

New Initialization Forms in C++11

December 5, 2015 | Article | No Comments

In C++11, initializing objects, arrays, and containers will become much easier than it used to be in C++03. In this article we will discuss about the use of new brace-initialization notation, class member initializers, and initialization list to write better and shorter code without compromising code safety or efficiency.

Initialization in C++03 is tricky with four different initialization notations and far too many arbitrary restrictions and loopholes:

  • No way to initialize a member array
  • No convenient form of initializing containers
  • No way to initialize dynamically allocated POD types

C++11 fixes these problems with new facilities for initializing objects. In this article, I present the new C++11 brace-initialization notation, discuss class member initialization, and explain how to initialize containers by using initializer lists.

C++03 Initialization: Four Initialization Notations

First let’s look at the C++03 initialization form. C++03 has various categories of initialization:

    • Initialization of fundamental types. The initialization of fundamental types uses the equal sign (=):
int n=0;
void*p=0;
char c='A';
    • Initialization of data members in a class and objects. Classes with a user-defined constructor require a constructor’s member initialization list (mem-init for short) for their data members. An object’s initializers are enclosed in parentheses in the object’s declaration:
//C++03 initialization of classes and objects
struct S1
{
  explicit S1(int n, int m) : x(n), y(m){} //mem-init
private:
  int x, y;
};

S1 s(0,1); //object initializers enclosed in parentheses
S1 s2={0,1}; //compilation error
    • Initialization of aggregates. Aggregate initialization requires braces, with the exception of string literals that may also appear between a pair of double quotes ([dp][dp]):
//C++03: POD arrays and structs are aggregates
int c1[2]={0,2};
char c2[]="message";
//or you can use the more verbose form:
char c3[]={'m','e','s','s','a','g','e','\0'};

struct S
{
  int a,b;
};

S s={0,1};

We also can use parentheses to initialize fundamental types as well. The parentheses in this case are interchangeable with the equal sign notation:

int n(0); //same as int n=0;
double d(0.5);

C++03 Initialization: Arbitrary Restrictions and Loopholes

C++03 imposes arbitrary restrictions in some cases, such as the inability to initialize member arrays:

class C
{
  int x[100];
  C(); //no proper way to initialize x
};

Similarly, we can’t initialize a dynamically allocated POD array:

char *buff=new char[1024]; //no proper way to initialize the elements of buff

Finally, there’s no easy way to initialize the elements of a Standard Library container. For instance, if you want to initialize a vector of strings, we would normally use a sequence of push_back() calls like this:

vector <string> vs;
vs.push_back("alpha");
vs.push_back("beta");
vs.push_back("gamma");

Fairly say, C++03 initialization is a mess. Now let’s see how C++11 tackles these problems with its new and uniform initialization notation.

Introducing C++11 Brace-Initialization

C++11 attempts to overcome the problems of C++03 initialization by introducing a universal initialization notation that applies to every type—whether a POD variable, a class object with a user-defined constructor, a POD array, a dynamically allocated array, or even a Standard Library container. The universal initializer is called a brace-init. It looks like this:

//C++11 brace-init
int a{0};
string s{"hello"};
string s2{s}; //copy construction
vector <string> vs{"alpha", "beta", "gamma"};
map<string, string> engineers
{ {"Satria", "+62 8977423935"},
  {"Ady", "++62 8977423936"}
};
double *pd= new double [3] {0.5, 1.2, 12.99};

class C
{
  int x[4];
public:
  C(): x{0,1,2,3} {}
};

 

Notice that unlike the traditional aggregate initializer of C and C++03, which uses braces after an equal sign (={}), the C++11 brace-init consists of a pair of braces (without the equal sign) in which the initializer(s) will be enclosed. An empty pair of braces indicates default initialization. Default initialization of POD types usually means initialization to binary zeros, whereas for non-POD types default initialization means default construction:

//C++11: default initialization using {}
int n{}; //zero initialization: n is initialized to 0
int *p{}; //initialized to nullptr
double d{}; //initialized to 0.0
char s[12]{}; //all 12 chars are initialized to '\0'
string s{}; //same as: string s;
char *p=new char [5]{}; // all five chars are initialized to '\0'

Class Member Initialization

C++11 pulls another rabbit out of its hat with class member initializers. Perhaps an example will best illustrate these:

class C
{
  int x=7; //class member initializer
public:
  C();
};

The data member x is automatically initialized to 7 in every instance of class C. In former dialects of C++, you would use the more cumbersome mem-init notation for the same purpose:

class C
{
  int x;
public:
  C() : x(7) {}
};

C++11 class member initializers are mostly a matter of convenience. They provide an overt and simplified form of initializing data members. But class member initializers also let you perform a few tricks that have hitherto been impossible. For example, you can use a class member initializer to initialize a member array:

class C
{
  int y[5] {1,2,3,4};
public:
  C();
};

Notice that a class member initializer can consist of any valid initialization expression, whether that’s the traditional equal sign, a pair of parentheses, or the new brace-init:

class C
{
  string s("abc");
  double d=0;
  char * p {nullptr};
  int y[5] {1,2,3,4};
public:
  C();
};

Regardless of the initialization form used, the compiler conceptually transforms every class member initializer into a corresponding mem-init. Thus, class C above is semantically equivalent to the following class:

class C2
{
  string s;
  double d;
  char * p;
  int y[5];
  public:
  C() : s("abc"), d(0.0), p(nullptr), y{1,2,3,4} {}
};

Bear in mind that if the same data member has both a class member initializer and a mem-init in the constructor, the latter takes precedence. In fact, you can take advantage of this behavior by specifying a default value for a member in the form of a class member initializer that will be used if the constructor doesn’t have an explicit mem-init for that member. Otherwise, the constructor’s mem-init will take effect, overriding the class member initializer. This technique is useful in classes that have multiple constructors:

class C
{
  int x=7; //class member initializer
  C(); //x is initialized to 7 when the default ctor is invoked
  C(int y) : x(y) {} //overrides the class member initializer
};
C c; //c.x = 7
C c2(5); //c.x = 5

Initializer Lists and Sequence Constructors

An initializer list lets you use a sequence of values wherever an initializer can appear. For example, you can initialize a vector in C++11 like this:

vector<int> vi {1,2,3,4,5,6};
vector<double> vd {0.5, 1.33, 2.66};

You may include as many initializers as you like between the braces. Although superficially this new syntax seems identical to the brace-init notation we discussed earlier, behind the scenes it’s a different story. C++11 furnishes every STL container with a new constructor type called a sequence constructor. A sequence constructor intercepts initializers in the form of {x,y...}. To make this machinery work, C++11 introduced another secret ingredient: an auxiliary class template called std::initializer_list<T>. When the compiler sees an initializer list, say {0.5, 1.33, 2.66}, it transforms the values in that list into an array of T with n elements (n is the number of values enclosed in braces) and uses that array to populate an implicitly generated initializer_list<T> object. The class template initializer_list has three member functions that access the array:

template<class E> class initializer_list
{
  //implementation (a pair of pointers or a pointer + length)
public:
  constexpr initializer_list(const E*, const E*); // [first,last)
  constexpr initializer_list(const E*, int); // [first, first+length)
  constexpr int size() const; // no. of elements
  constexpr const T* begin() const; // first element
  constexpr const T* end() const; // one more than the last element
};

To better understand how the compiler handles initializer lists of containers, let’s dissect a concrete example. Suppose your code contains the following declaration of a vector:

vector<double> vd {0.5, 1.33, 2.66};

The compiler detects the initializer list {0.5, 1.33, 2.66} and performs the following steps:

  1. Detect the type of the values in the initializer list. In the case of {0.5, 1.33, 2.66}, the type is double.
  2. Copy the values from the list into an array of three doubles.
  3. Construct an initializer_list<double> object that “wraps” the array created in the preceding step.
  4. Pass the initializer_list<double> object by reference to vd‘s sequence constructor. The constructor in turn allocates n elements in the vector object, initializing them with the values of the array.

It’s hard to imagine that so much is going on behind the scenes every time you initialize an STL container with a pair of braces! The good news is that you don’t have to do anything for this magic to happen—it just works. Of course, you still need a C++11-compliant compiler as well as a C++11-compliant Standard Library to use initializer lists. Make sure that your target project is built with the appropriate compilation options, too.

Conclusion

The C++ standards committee invested a lot of time and effort in finding a solution to the limitations of C++03 initialization. It looks like they succeeded. Historically, brace-init, class member initializers, and initializer lists were three independent proposals. Later, they were revised to ensure compatibility and uniformity. Together, these three initialization-related features make C++11 programming simpler and more intuitive. You will surely appreciate them next time you initialize a dynamically allocated array—or, indeed, a vector.

Implementation of Delegates in C++11

December 5, 2015 | Article | 1 Comment

Introduction

In C++, it would be useful to be able to bind an object with its member function and produce a global function. Such features exists in other languages, for example C#. In C++, there are member function pointers but they do not provide the feature we talk about. In this article we will discuss about a simple implementation of delegates in C++ using member function pointers and C++11 using variadic templates.

For this article, I use:

  1. Slackware64 14.0 with gcc 4.7.1
  2. Windows 8 with Visual Studio 2010 express

Background

The approach is to provide a function create_delegate, which can be called in one of the following ways:

  • create_delegate(&object, &member_function)
  • create_delegate(&function)

The first option creates an object with a member operator() that can be called as a function. The second produces a function pointer, which is the same as &function. Both these values are compatible with type type function<...>.

A Sample Program

Let’s define a class with several methods

class A {
	int i;
public:
	A(int k):i(k) {}

	auto get()const ->int { return i; }
	auto set(int v)->void { i = v; }

	auto inc(int g)->int& { i+=g; return i; }
	auto incp(int& g)->int& { g+=i; return g; }

	auto f5 (int a1, int a2, int a3, int a4, int a5)const ->int {
		return i+a1+a2+a3+a4+a5;
	}

	auto set_sum4(int &k, int a1, int a2, int a3, int a4)->void {
		i+=a1+a2+a3+a4;
		k = i;
	}

	auto f8 (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const ->int {
		return i+a1+a2+a3+a4+a5+a6+a7+a8;
	}

	static auto sqr(double x)->double { return x*x; }

	auto g1(const int& n)->void { std::cout << "g1: " << n <<  std::endl; }
	auto g2(int&& n)->void { std::cout << "g2: " << n <<  std::endl; }
	auto g3(int& n)->int&  { n++; return n; }
	auto g4(int n)-<int    { return 10*n; }
};

Please note that in source code above we use C++11 convention using auto and new function declaration syntax. It is not absolutely a requirement to do so, hence you can also define the class using traditional way of declaration like good all C++ program.

In the program, we can create a class as follows:

A a(11)

Now, to create delegates:

[sourcecode language="c++"]
auto set1 = create_delegate(&a,&A::set);
auto inc = create_delegate(&a,&aA::inc);
std::function<int(int&)> incp = create_delegate(&a,&A::incp);
auto af5  = create_delegate(&a,&A::f5);
auto set_sum4= create_delegate(&a,&A::set_sum4);
auto af8  = create_delegate(&a,&A::f8);
auto sqr = create_delegate(&A::sqr); // static function, not a member
auto g1  = create_delegate(&a,&A::g1);
auto g2  = create_delegate(&a,&A::g2);
auto g3  = create_delegate(&a,&A::g3);
auto g4  = create_delegate(&a,&A::g4);
[/sourcecode]

As demonstrated, we can use auto or function<…>. Now we can invoke the delegates:

set1(25);
int x = 5;
int k = inc(x);
int k2 = incp(x);
k2 *= 7;
std::cout << "a.get():" << a.get() << std::endl;
std::cout << "k: " << k << std::endl;
std::cout << "x: " << x << std::endl;
std::cout << "af5(1,2,3,4,5): " << af5(1,2,3,4,5) << std::endl;

set_sum4(x,1,2,3,20);
std::cout << "after set_sum4(x,1,2,3,20)" << std::endl;
std::cout << "a.get(): " << a.get() << std::endl;
std::cout << "x: " << x << std::endl;
std::cout << "af8(1,2,3,4,5,6,7,8): " << af8(1,2,3,4,5,6,7,8) << std::endl;
std::cout << "sqr(2.1): " << sqr(2.1) << std::endl;
g1(100);
g2(32+5);
int p = 15;
int& g = g3(p);
int s = g4(35);
g++;
std::cout << "p: " << p << std::endl;
std::cout << "s: " << s << std::endl;

The program will print:

a.get():30
k: 30
x: 35
af5(1,2,3,4,5): 45
after set_sum4(x,1,2,3,20)
a.get(): 56
x: 56
af8(1,2,3,4,5,6,7,8): 92
sqr(2.1): 4.41
g1: 100
g2: 37
p: 17
s: 350

Points about the implementation

For a simple member function that is not volatile or const, the implementation would be very simple. We have to create a class that will store the two pointers: one to the object and the other to the its member function:

template <class T, class R, class ... P>
struct  _mem_delegate {
	T* m_t;
	R  (T::*m_f)(P ...);
	_mem_delegate(T* t, R  (T::*f)(P ...) ):m_t(t),m_f(f) {}
	R operator()(P ... p) {
			return (m_t->*m_f)(p ...);
	}
};

But the return statement needs some correction. The problem is that if a function has an rvalue-reference argument (like auto g2(int&& n)->void), this will not work. Such a parameter in the body of the function is not an rvalue any more, it’s an lvalue. Then we have two options:

  1. Use forwarding return (m_t->*m_f)(std::forward<P>(p) …);
  2. Just convert using static_cast such that return (m_t->*m_f)(static_cast<P>(p) …);

Both options will work at this point. The first underlines the idea, the second is more general.

The variadic template allows us to define operator() with flexible number and types of parameters. The create_function implementation will simply return an object of this class:

template <class T, class R, class ... P>
_mem_delegate<T,R,P ...> create_delegate(T* t, R (T::*f)(P ...)) {
	_mem_delegate<T,R,P ...> d(t,f);
	return d;
}

Practically, there is needed extra three implementations to cover cases of member functions which are const, volatile and const volatile. That’s why traditional macros, using #define, are handy: they allow us to avoid rewriting the same code fragments. Here is the full implementation:

template <class F>
F* create_delegate(F* f) {
	return f;
}

#define _MEM_DELEGATES(_Q,_NAME)\
template <class T, class R, class ... P>\
struct _mem_delegate ##_NAME\
{\
	T* m_t;\
	R  (T::*m_f)(P ...) _Q;\
	_mem_delegate ##_NAME(T* t, R  (T::*f)(P ...) _Q):m_t(t),m_f(f) {}\
	R operator()(P ... p) _Q\
	{\
		return (m_t->*m_f)(std::forward<P>(p) ...);\
	}\
};\
\
template <class T, class R, class ... P>\
	_mem_delegate ##_NAME<T,R,P ...> create_delegate(T* t, R (T::*f)(P ...) _Q)\
{\
	_mem_delegate ##_NAME<T,R,P ...> d(t,f);\
	return d;\
}

_MEM_DELEGATES(,Z)
_MEM_DELEGATES(const,X)
_MEM_DELEGATES(volatile,Y)
_MEM_DELEGATES(const volatile,W)

A more meaningful example: calculating the length of a curve

In this section we will consider a sample practical problem and look at various approaches, and show some alternative methods to delegates.

Calculation of the length of a curve: global functions

The function CurveLength can be used to calculate the length of a curve, which is defined by two functions fx(t) and fy(t), where t is in the range [a,b]. The parameter n is the number of step we take, and it affects the precision.

auto CurveLength(auto (*fx)(double)->double, auto (*fy)(double)->double, double a, double b,   int n = 20000)
				 ->double
{
	double s = 0.0;
	double h = (b-a)/n;
	double t = a;
	double x0 = fx(t);
	double y0 = fy(t);
	for (int i = 0; i < n; i++) {
		t += h;
		double x1 = fx(t);
		double y1 = fy(t);
		double dx = x1-x0;
		double dy = y1-y0;
		s += sqrt(dx*dx + dy*dy);
		x0 = x1;
		y0 = y1;
	};
	return s;
}

A simple C-style approach would be to define the curves we need as global functions, and if we need to parameterize the curve we will define global variables. We look at an ellipse and a cycloid. The cycloid length is easily calculated analytically. As for the ellipse, if the a and b axes are equal, it will be a circle, otherwise its length cannot be expressed by a simple formula. Below is our definition of the two curves:

//Cycloid

double cycloid_a;
auto Cycloid_fx(double t)->double {
	return cycloid_a*(1 - cos(t));
}

auto Cycloid_fy(double t)->double {
	return cycloid_a*(t - sin(t));
}

//Ellipse
double ellipse_a;
double ellipse_b;

auto Ellipse_fx(double t)->double {
	return ellipse_a*cos(t);
}

auto Ellipse_fy(double t)->double {
	return ellipse_b*sin(t);
}

Here is a sample program to calculate their sizes:

double PI = 4*atan(1.0);

ellipse_a = 1.0;
ellipse_b = 1.0;

cycloid_a = 1.0;

std::cout << std::setprecision(10) << std::setw(10);

std::cout <<  "ellipse1: " << CurveLength(Ellipse_fx, Ellipse_fy, 0.0,2*PI) << std::endl;
std::cout <<  "cycloid1: " << CurveLength(Cycloid_fx, Cycloid_fy, 0.0,2*PI) << std::endl;

ellipse_a = 3.0;
ellipse_b = 1.0;

cycloid_a = 5.0;

std::cout <<  "ellipse2: " << CurveLength(Ellipse_fx, Ellipse_fy, 0.0,2*PI) << std::endl;
std::cout <<  "cycloid2: " << CurveLength(Cycloid_fx, Cycloid_fy, 0.0,2*PI) << std::endl;

 

The program will print:

ellipse1: 6.283185281
cycloid1: 7.999999992
ellipse2: 13.36489317
cycloid2: 39.99999996

The disadvantage of this approach is that all functions and their parameters are global.

An abstract class and virtual functions

A traditional, good C++ approach is to use an abstract class and define a member function CurveLength, which uses the member functions fx(t) and fy(t):

class Curve {
public:
	virtual auto fx(double t)->double = 0;
	virtual auto fy(double t)->double = 0;

	auto CurveLength(double a, double b, int n = 20000)->double {
		double s = 0.0;
		double h = (b-a)/n;
		double t = a;
		double x0 = fx(t);
		double y0 = fy(t);
		for (int i = 0; i < n; i++) {
			t += h;
			double x1 = fx(t);
			double y1 = fy(t);
			double dx = x1-x0;
			double dy = y1-y0;
			s += sqrt(dx*dx + dy*dy);
			x0 = x1;
			y0 = y1;
		}
		return s;
	}
};

class Cycloid: public Curve {
	double m_a;
public:
	Cycloid(double a):m_a(a) {}

	virtual auto fx(double t)->double {
		return m_a*(1 - cos(t));
	}

	virtual auto fy(double t)->double {
		return m_a*(t - sin(t));
	}
};

class Ellipse: public Curve
{
	double m_a;
	double m_b;
public:
    Ellipse(double a, double b):m_a(a),m_b(b) {}

	virtual auto fx(double t)->double {
		return m_a*cos(t);
    }

	virtual auto fy(double t)->double {
		return m_b*sin(t);
	}
};

The program will look like this:

double PI = 4*atan(1.0);

Ellipse ellipse1(1.0,1.0);
Cycloid cycloid1(1.0);

std::cout << std::setprecision(10) << std::setw(10);

std::cout <<  "ellipse1: " << ellipse1.CurveLength(0.0,2*PI) << std::endl;
std::cout <<  "cycloid1: " << cycloid1.CurveLength(0.0,2*PI) << std::endl;

Ellipse ellipse2(3.0,1.0);
Cycloid cycloid2(5.0);

std::cout <<  "ellipse2: " << ellipse1.CurveLength(0.0,2*PI) << std::endl;
std::cout <<  "cycloid2: " << cycloid1.CurveLength(0.0,2*PI) << std::endl;

 

The problem is that all the curves have to be derived from the same base class, and if we want to use CurveLength in a library the class Curve should be part of it.

Using delegates

Delegates allow us to deal with unrelated classes. Here is the approach using delegates:

auto CurveLength(std::function<double(double)> fx, std::function<double(double)> fy, double a, double b, int n = 20000)->double {
	double s = 0.0;
	double h = (b-a)/n;
	double t = a;
	double x0 = fx(t);
	double y0 = fy(t);
	for (int i = 0; i < n; i++) {
		t += h;
		double x1 = fx(t);
		double y1 = fy(t);
		double dx = x1-x0;
		double dy = y1-y0;
		s += sqrt(dx*dx + dy*dy);
		x0 = x1;
		y0 = y1;
	}
	return s;
}

double PI = 4.0*atan(1.0);

class Cycloid {
	double m_a;
public:
	Cycloid(double a):m_a(a) {}

	auto fx(double t)->double {
		return m_a*(1 - cos(t));
	}

	auto fy(double t)->double {
		return m_a*(t - sin(t));
	}
};

class Ellipse {
	double m_a;
	double m_b;
public:
	Ellipse(double a, double b):m_a(a),m_b(b) {}

	auto getX(double t)->double {
		return m_a*cos(t);
	}

	auto getY(double t)->double {
		return m_b*sin(t);
	}
};

 

I have deliberately given different names to member functions. These two classes are unrelated. Here is a program:

int main() {
	Ellipse ellipse1(1.0,1.0);
	Cycloid cycloid1(1.0);

	auto ellipse1_fx = create_delegate(&ellipse1,&Ellipse::getX);
	auto ellipse1_fy = create_delegate(&ellipse1,&Ellipse::getY);
	auto cycloid1_fx = create_delegate(&cycloid1,&Cycloid::fx);
	auto cycloid1_fy = create_delegate(&cycloid1,&Cycloid::fy);

	std::cout << std::setprecision(10) << std::setw(10);

	std::cout <<  "ellipse1: " << CurveLength(ellipse1_fx, ellipse1_fy, 0.0,2*PI) << std::endl;
	std::cout <<  "cycloid1: " << CurveLength(cycloid1_fx, cycloid1_fy, 0.0,2*PI) << std::endl;

	Ellipse ellipse2(3.0,1.0);
	Cycloid cycloid2(5.0);
	auto ellipse2_fx = create_delegate(&ellipse2,&Ellipse::getX);
	auto ellipse2_fy = create_delegate(&ellipse2,&Ellipse::getY);
	auto cycloid2_fx = create_delegate(&cycloid2,&Cycloid::fx);
	auto cycloid2_fy = create_delegate(&cycloid2,&Cycloid::fy);

	std::cout <<  "ellipse2: " << CurveLength(ellipse2_fx, ellipse2_fy, 0.0,2*PI) << std::endl;
	std::cout <<  "cycloid2: " << CurveLength(cycloid2_fx, cycloid2_fy, 0.0,2*PI) << std::endl;

	return 0;
}

 

Delegates allow us to use the same functions for various curve classes, which are completely unrelated. This CurveLength can be part of the library.

An alternative approach: using lambdas

The C++11 lambdas make it possible to define functions immediately and also to capture the variables from the environment. The CurveLength and the curve classes can be defined exactly the same as in the example with delegates, but the program, the function calls change:

int main() {
	Ellipse ellipse1(1.0,1.0);
	Cycloid cycloid1(1.0);

	auto ellipse1_fx = create_delegate(&ellipse1,&Ellipse::getX);
	auto ellipse1_fy = create_delegate(&ellipse1,&Ellipse::getY);
	auto cycloid1_fx = create_delegate(&cycloid1,&Cycloid::fx);
	auto cycloid1_fy = create_delegate(&cycloid1,&Cycloid::fy);

	std::cout << std::setprecision(10) << std::setw(10);

	std::cout <<  "ellipse1: " << CurveLength(ellipse1_fx, ellipse1_fy, 0.0,2*PI) << std::endl;
	std::cout <<  "cycloid1: " << CurveLength(cycloid1_fx, cycloid1_fy, 0.0,2*PI) << std::endl;

	Ellipse ellipse2(3.0,1.0);
	Cycloid cycloid2(5.0);
	auto ellipse2_fx = create_delegate(&ellipse2,&Ellipse::getX);
	auto ellipse2_fy = create_delegate(&ellipse2,&Ellipse::getY);
	auto cycloid2_fx = create_delegate(&cycloid2,&Cycloid::fx);
	auto cycloid2_fy = create_delegate(&cycloid2,&Cycloid::fy);

	std::cout <<  "ellipse2: " << CurveLength(ellipse2_fx, ellipse2_fy, 0.0,2*PI) << std::endl;
	std::cout <<  "cycloid2: " << CurveLength(cycloid2_fx, cycloid2_fy, 0.0,2*PI) << std::endl;

	return 0;
}

I deliberately show two approaches to capture variables: a specific one [&ellipse1] , and general [&]. Either can be used. Lambdas are easy to use, but syntax becomes longer if you have to deal with more parameters. In the end, it’s your choice.

C++ Ranged Based Loop

November 24, 2015 | Article | No Comments

C++11 has bring some nice usability improvements to the language. It removes unnecessary typing and other barriers to getting code written quickly. One example we’ve already covered is the new meaning of the auto keyword; now I’d like to talk more about the range-based for loop–both how to use it, and how to make your own classes work with it.

Basic syntax for range-based for loops

Nowadays, almost every programming language has a convenient way to write a for loop over a range of values. Finally, C++ has the same concept; you can provide a container to your for loop, and it will iterate over it. We’ve already seen a few basic examples in What is C++11? To refresh your memory, the range-based for loop looks like this:

stc::vector<int> vec;
vec.push_back( 10 );
vec.push_back( 20 );

for (int i : vec )
{
    cout << i;
}

This code prints the contents of a vector called vec, with the variable i taking on the value of each element of the vector, in series, until the end of the vector is reached.

You can use auto in the type, to iterate over more complex data structures conveniently–for example, to iterate over a map you can write

std::map<std::string, std::string> address_book;
for ( auto address_entry : address_book )
{
            cout  << address_entry.first << " < " << address_entry.second << ">" << endl;
}

And you don’t need to worry about spelling out the iterator type.

Modifying the Contents of the Vector

If you want to modify the values in the container you’re looping over, or if you want to avoid copying large objects, and the underlying iterator supports it, you can make the loop variable a reference. For example, here’s a loop that increments each element in an integer vector:

std::vector<int> vec;
vec.push_back( 1 );
vec.push_back( 2 );

for (int& i : vec )
{
    i++; // increments the value in the vector
}
for (int i : vec )
{
    // show that the values are updated
    cout << i << endl;
}

What does it mean to have a range?

Strings, arrays, and all STL containers can be iterated over with the new range-based for loop already. But what if you want to allow your own data structures to use the new syntax?

In order to make a data structure iterable, it must work similarly to the existing STL iterators.

There must be begin and end methods that operate on that structure, either as members or as stand-alone functions, and that return iterators to the beginning and end of the structure
The iterator itself must support an operator* method, an operator != method, and an operator++ method, either as members or as stand-alone functions (you can read more about operator overloading)

Note that operator++ should be the prefix version, which is done by declaring a function called operator++ that takes no arguments.

That’s it! With these five functions, you can have a data structure that works with a range-based for loop. Because the begin and end methods can be non-member functions ( begin( container ) instead of container.begin() ), you can even adapt existing data structures that don’t natively support the STL-style iterators. All you must do is create your own iterator that supports *, prefix increment (++itr) and != and that has a way of defining a begin iterator and an end iterator.

Since range-based for loops are so nice, I suspect that most new containers that don’t already support the STL iterator model will want to add adaptors of some sort that allow range-based for loops to be used. Here’s a small program that demonstrates creating a simple iterator that works with a range-based for loops. In it, I create an IntVector type that is fixed at a size of 100, and that can be iterated over using a class called Iter. I’ve made this code const-correct, but if you haven’t seen that concept before, the code works just fine with every const removed.

#include <iostream>
using namespace std;

// forward-declaration to allow use in Iter
class IntVector;

class Iter
{
    public:
    Iter (const IntVector* p_vec, int pos)
        : _pos( pos )
        , _p_vec( p_vec )
    { }

    // these three methods form the basis of an iterator for use with
    // a range-based for loop
    bool
    operator!= (const Iter& other) const
    {
        return _pos != other._pos;
    }

    // this method must be defined after the definition of IntVector
    // since it needs to use it
    int operator* () const;

    const Iter& operator++ ()
    {
        ++_pos;
        // although not strictly necessary for a range-based for loop
        // following the normal convention of returning a value from
        // operator++ is a good idea.
        return *this;
    }

    private:
    int _pos;
    const IntVector *_p_vec;
};

class IntVector
{
    public:
    IntVector ()
    {
    }

    int get (int col) const
    {
        return _data[ col ];
    }
    Iter begin () const
    {
        return Iter( this, 0 );
    }

    Iter end () const
    {
        return Iter( this, 100 );
    }

    void set (int index, int val)
    {
        _data[ index ] = val;
    }

    private:
   int _data[ 100 ];
};

int
Iter::operator* () const
{
     return _p_vec->get( _pos );
}

// sample usage of the range-based for loop on IntVector
int main()
{
    IntVector v;
    for ( int i = 0; i < 100; i++ )
    {
        v.set( i , i );
    }
    for ( int i : v ) { cout << i << endl; }
}

One thing to notice about this code is that it does not allow modification of elements in the IntVector by using a reference in the for loop. You should be able to add this easily by changing the return value of get to be a reference, but this would make the code much longer by requiring the addition of non-const methods, and I wanted to focus on the basic structure.

C++ has from the beginning attempted to improve on the type system of C, adding features like classes that let you build better types and enums, which eliminate the need for some uses of the preprocessor (which is not at all type safe). C++ also performs fewer implicit type conversions for you (such as not allowing implicit assignment from void*), letting the compiler find more bugs for you.

C++11 goes even further. Even though enums got rid of the need for integer #define constants, we still had the ugly, poorly typed NULL pointer. C++11 cleans this up by adding new explicit, clear nullptr value with its own type. C++11 also brings new, strongly typed enums. In this article, we’ll cover both these improvements.

Why do we need strongly typed enums?

So why do we need strongly typed enums anyway? Old-style C++ enums are essentially integers; they could be compared with integers or with other enums of different types. The thing is, you normally don’t want to do that since enums are supposed to be some fixed list of enumerated values. Why would you want to compare to some other enum type (or an integer)? It’s like saying, “please compare this kind of nail with this kind of toothbrush.” It makes no sense, and you probably don’t mean to do it. But old-style C++ enums will happily tell you, “why yes, this nail isn’t like this toothbrush” or, worse, they might compare equal because they happen to share the same underlying integer value (“ah yes, this nail IS a Panasonic electronic toothbrush”). Now, with strongly typed enums, the compiler will tell you that you’re doing it. If you really mean it, you can always use a typecast.

Another limitation is that enum values were unscoped–in other words, you couldn’t have two enumerations that shared the same name:

// this code won't compile!
enum Color {RED, GREEN, BLUE};
enum Feelings {EXCITED, MOODY, BLUE};

Strongly typed enums – enum classes

Enter strongly typed enums–and I don’t mean enums. Strongly typed enums are a new kind of enum, declared like so:

// this code will compile (if your compiler supports C++11 strongly typed enums)
enum class Color {RED, GREEN, BLUE};
enum class Feelings {EXCITED, MOODY, BLUE};

The use of the word class is meant to indicate that each enum type really is different and not comparable to other enum types. Strongly typed enums, enum classes, also have better scoping. Each enum value is scoped within the name of the enum class. In other words, to access the enum values, you must write:

Color color = Color::GREEN;
if ( Color::RED == color )
{
    // the color is red
}

Old style C++ enums are still available–if you want them–largely for backward compatibility with existing code bases. They did pick up one trick; you can now, optionally, put the enum name in front of the value: Color::RED. But since this is optional, it doesn’t solve any naming conflicts; it just makes it a little bit more clear.

Enum classes have another advantages over old-style enums. You can have a forward declaration to a strongly typed enum, meaning that you can write code like:

enum class Mood;

void assessMood (Mood m);

// later on:
enum class Mood { EXCITED, MOODY, BLUE };

Why would this be useful? Forward declarations are often about the physical layout of code on disk into different files or to provide opaque objects as part of an API. In the first case, where you care about the physical disk layout, using a forward declaration allows you to declare an enum type in the header file while putting specific values into the cpp file. This lets you change the list of possible enum values quite frequently without forcing all dependent files to recompile. In the second case, an enum class can be exposed as a type-safe but otherwise opaque value returned from one API function to be passed into another API function. The code using the API need not know the possible values the type can take on. Since the compiler still knows about the type, it can enforce that variables declared to work with that type are not confused with variables working with another type.

Well-defined enum sizes
A final advantage of enum classes is that you can set the size of your enum–you can use any signed or unsigned integer type. It defaults to int, but you can also use char, unsigned long, etc. This will ensure some measure of compatibility across compilers.

// we only have three colors, so no need for ints!
enum class Colors : char { RED = 1, GREEN = 2, BLUE = 3 };

But in C++11, we can do even better, specifying exact sizes for enums, using cstdint.

<cstdint>
One problem that C++ has suffered from is a lack of standard types that provide fixed, well-defined sizes. For example, sometimes you want to have a 32-bit integer, not just an int that might have different sizes on different architectures. In C++11, the C99 header file stdint.h has been included as cstdint. The cstdint header includes types such as std::int8_t, std::int16_t, std::int32_t, and std::int64_t (as well as unsigned versions that begin with u: std::uint8_t).

Here’s an example that combines these new types with enum classes to get completely known sizes for your enum across compilers and architectures:

#include <cstdint>
enum class Colors : std::int8_t { RED = 1, GREEN = 2, BLUE = 3 };

nullptr

In C and C++, it’s always been important to express the idea of a NULL pointer–one that has no value. Oddly, in C++, the expression used, 0 (or NULL, always #defined to zero) was not even a pointer type. Although this worked most of the time, it could lead to strange and unexpected problems in what are, admittedly, rather edge cases. For example imagine you have the following two function declarations:

void func(int n);
void func(char *s);

func( NULL ); // guess which function gets called?

Although it looks like the second function will be called–you are, after all, passing in what seems to be a pointer–it’s really the first function that will be called! The trouble is that because NULL is 0, and 0 is an integer, the first version of func will be called instead. This is the kind of thing that, yes, doesn’t happen all the time, but when it does happen, is extremely frustrating and confusing. If you didn’t know the details of what is going on, it might well look like a compiler bug. A language feature that looks like a compiler bug is, well, not something you want.

Enter nullptr. In C++11, nullptr is a new keyword that can (and should!) be used to represent NULL pointers; in other words, wherever you were writing NULL before, you should use nullptr instead. It’s no more clear to you, the programmer, (everyone knows what NULL means), but it’s more explicit to the compiler, which will no longer see 0s everywhere being used to have special meaning when used as a pointer.
std::nullptr_t

nullptr, by the way, is not only declared to be a pointer and convert implicitly to all pointer types (and bool), but it is its own special, distinct type:

decltype( nullptr )

While we can use decltype to extract its type, there is also a more convenient notation:

std::nullptr_t

Since nullptr is its own unique type, you can use it as a constructor or function argument when you want to be sure that you only ever take an empty pointer for a value. For example:

void func( std::nullptr_t );

declares a function that takes only nullptr (or a value cast to std::nullptr_t) and nothing else, a rather neat trick.

Regardless of all this–the rule of thumb for C++11 is simply to start using nullptr whenever you would have otherwise used NULL in the past.

References: http://www.cprogramming.com/c++11/c++11-nullptr-strongly-typed-enum-class.html

Multithreading Programming in C++11

November 24, 2015 | Article | 1 Comment

Before C++11, C++ doesn’t support multi-threading natively. A C++ program for threading must depend on others threading implementation. That is a source code for Windows threading is different with POSIX-Unix threading. But the newest standard has including multithreading support natively. Hurray!

Let’s begin by creating and launching a thread in C++11.

[sourcecode language="cpp"]
#include <iostream>
#include <thread>
using namespace std;

void thread_main() {            // Entry point for thread
cout<<"Hello world"<<endl;
}
int main() {
thread thr(thread_main);    // Create a thread
thr.join();                      // Join the thread with main thread
}
[/sourcecode]

On Linux we can compile it with g++

g++ -std=c++0x -pthread filename.cpp

Of course as a different thread, the thread_main() be run independent form the main thread. In above example, after create new thread, we join the new thread with main thread so the main function will wait for the thread to finish. Because it is running independently, we cannot guarantee if thread_main() would exit before main() if we did not join them.

Now let’s look equivalent code using POSIX threads:

#include <iostream>
#include <pthread.h>
using namespace std;

//This function will be called from a thread
void *thread_main(void *) {
   cout << "Launched by thread" << endl;
   return NULL;
}

int main() {
   pthread_t t;

   //Launch a thread
   pthread_create(&t, NULL, thread_main, NULL);

   //Join the thread with the main thread
   pthread_join(t, NULL);
   return 0;
}

We can also launch more than one thread at once to achieve parallelism we want. In order to do this we could create an array of threads. Using the same source code as previous, let’s modify some parts:

#include <iostream>
#include <thread>
using namespace std;

static const int nmThreads = 10;
void thread_main(int arg) {
   cout<<"Launch by thread "<<arg<<endl;
}

int main() {
   thread T[nmThreads];

   // launch a group of threads
   for(int i=0; i<nmThreads; i++) {
      T[i] = thread(thread_main,i);
   }
   cout<<"Launch from the main\n";

   // Join the threads with the main thread
   for(int i=0; i<nmThreads; i++) {
      T[i].join();
   }
   return 0;
}

So how many threads we have? Yes, 11 including main. The above code runs 11 threads on a single process.

That is, running a multithreading on C++11 is now easier. Let see what we could expect later.

Move Semantics and rvalue references in C++11

November 24, 2015 | Article | No Comments

C++ has always produced fast programs. Unfortunately, until C++11, there has been an obstinate wart that slows down many C++ programs: the creation of temporary objects. Sometimes these temporary objects can be optimized away by the compiler (the return value optimization, for example). But this is not always the case, and it can result in expensive object copies.

Let’s say that we have the following code:

#include <iostream>
using namespace std;

vector<int> doubleValues (const vector<int>& v) {
   vector<int> new_values( v.size() );
   for (auto itr = new_values.begin(), end_itr = new_values.end(); itr != end_itr; ++itr )
   {
      new_values.push_back( 2 * *itr );
   }
   return new_values;
}

int main() {
   vector<int> v;
   for ( int i = 0; i < 100; i++ ) {
      v.push_back( i );
   }
   v = doubleValues( v );
}

If you’ve done a lot of high performance work in C++, sorry about the pain that brought on. If you haven’t–well, let’s walk through why this code is terrible C++03 code. (The rest of this tutorial will be about why it’s fine C++11 code.) The problem is with the copies. When doubleValues is called, it constructs avector, new_values, and fills it up. This alone might not be ideal performance, but if we want to keep our original vector unsullied, we need a second copy. But what happens when we hit the return statement?

The entire contents of new_values must be copied! In principle, there could be up to two copies here: one into a temporary object to be returned, and a second when the vector assignment operator runs on the line v = doubleValues( v );. The first copy may be optimized away by the compiler automatically, but there is no avoiding that the assignment to v will have to copy all the values again, which requires a new memory allocation and another iteration over the entire vector.

This example might be a little bit contrived–and of course you can find ways to avoid this kind of problem–for example, by storing and returning the vector by pointer, or by passing in a vector to be filled up. The thing is, neither of these programming styles is particularly natural. Moreover, an approach that requires returning a pointer has introduced at least one more memory allocation, and one of the design goals of C++ is to avoid memory allocations.

The worst part of this whole story is that the object returned from doubleValues is a temporary value that’s no longer needed. When you have the line v = doubleValues( v ), the result of doubleValues( v ) is just going to get thrown away once it is copied! In theory, it should be possible to skip the whole copy and just pilfer the pointer inside the temporary vector and keep it in v. In effect, why can’t wemovethe object? In C++03, the answer is that there was no way to tell if an object was a temporary or not, you had to run the same code in the assignment operator or copy constructor, no matter where the value came from, so no pilfering was possible. In C++11, the answer is–you can!

That’s what rvalue references and move semantics are for! Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.

Move semantics relies on a new feature of C++11, called rvalue references, which you’ll want to understand to really appreciate what’s going on. So first let’s talk about what an rvalue is, and then what an rvalue reference then. Finally, we’ll come back to move semantics and how it can be implemented with rvalue references.

Rvalues and Lvalues – bitter rivals, or best of friends?

In C++, there are rvalues and lvalues. An lvalue is an expression whose address can be taken, a locator value–essentially, an lvalue provides a (semi)permanent piece of memory. You can make assignments to lvalues. For example:

int a;
a = 1; // here, a is an lvalue

You can also have lvalues that aren’t variables:

int x;
int& getRef ()
{
   return x;
}

getRef() = 4;

Here, getRef returns a reference to a global variable, so it’s returning a value that is stored in a permanent location. (You could literally write & getRef() if you wanted to, and it would give you the address of x.)

Rvalues are–well, rvalues are not lvalues. An expression is an rvalue if it results in a temporary object. For example:

int x;
int getVal ()
{
   return x;
}
getVal();

Here, getVal() is an rvalue–the value being returned is not a reference to x, it’s just a temporary value. This gets a little bit more interesting if we use real objects instead of numbers:

string getName ()
{
   return "Xathrya";
}
getName();

Here, getName returns a string that is constructed inside the function. You can assign the result of getName to a variable:

string name = getName();

But you’re assigning from a temporary object, not from some value that has a fixed location. getName() is an rvalue.

Detecting Temporary objects with rvalue references

The important thing is that rvalues refer to temporary objects–just like the value returned from doubleValues. Wouldn’t it be great if we could know, without a shadow of a doubt, that a value returned from an expression was a temporary, and somehow write code that is overloaded to behave differently for temporary objects? Why, yes, yes indeed it would be. And this is what rvalue references are for. An rvalue reference is a reference that will bind only to a temporary object. What do I mean?

Prior to C++11, if you had a temporary object, you could use a “regular” or “lvalue reference” to bind it, but only if it was const:

const string& name = getName(); // ok
string& name = getName(); // NOT ok

The intuition here is that you cannot use a “mutable” reference because, if you did, you’d be able to modify some object that is about to disappear, and that would be dangerous. Notice, by the way, that holding on to a const reference to a temporary object ensures that the temporary object isn’t immediately destructed. This is a nice guarantee of C++, but it is still a temporary object, so you don’t want to modify it.

In C++11, however, there’s a new kind of reference, an “rvalue reference”, that will let you bind a mutable reference to an rvalue, but not an lvalue. In other words, rvalue references are perfect for detecting if a value is temporary object or not. Rvalue references use the && syntax instead of just &, and can be const and non-const, just like lvalue references, although you’ll rarely see a const rvalue reference (as we’ll see, mutable references are kind of the point):

const string&& name = getName(); // ok
string&& name = getName(); // also ok - praise be!

So far this is all well and good, but how does it help? The most important thing about lvalue references vs rvalue references is what happens when you write functions that take lvalue or rvalue references as arguments. Let’s say we have two functions:

printReference (const String& str)
{
   cout << str;
}

printReference (String&& str)
{
   cout << str;
}

Now the behavior gets interesting–the printReference function taking a const lvalue reference will accept any argument that it’s given, whether it be an lvalue or an rvalue, and regardless of whether the lvalue or rvalue is mutable or not. However, in the presence of the second overload, printReference taking an rvalue reference, it will be given all values except mutable rvalue-references. In other words, if you write:

string me( "Xathrya" );
printReference(  me ); // calls the first printReference function, taking an lvalue reference

printReference( getName() ); // calls the second printReference function, taking a mutable rvalue reference

Now we have a way to determine if a reference variable refers to a temporary object or to a permanent object. The rvalue reference version of the method is like the secret back door entrance to the club that you can only get into if you’re a temporary object (boring club, I guess). Now that we have our method of determining if an object was a temporary or a permanent thing, how can we use it?

Move constructor and move assignment operator

The most common pattern you’ll see when working with rvalue references is to create a move constructor and move assignment operator (which follows the same principles). A move constructor, like a copy constructor, takes an instance of an object as its argument and creates a new instance based on the original object. However, the move constructor can avoid memory reallocation because we know it has been provided a temporary object, so rather than copy the fields of the object, we will move them.

What does it mean to move a field of the object? If the field is a primitive type, like int, we just copy it. It gets more interesting if the field is a pointer: here, rather than allocate and initialize new memory, we can simply steal the pointer and null out the pointer in the temporary object! We know the temporary object will no longer be needed, so we can take its pointer out from under it.

Imagine that we have a simple ArrayWrapper class, like this:

class ArrayWrapper
{
public:
   ArrayWrapper (int n) 
   : _p_vals( new int[ n ] ), _size( n ) {}
   // copy constructor
   ArrayWrapper (const ArrayWrapper& other) 
   : _p_vals( new int[other._size  ] ) , _size( other._size )
   {
      for ( int i = 0; i < _size; ++i )
      {
         _p_vals[ i ] = other._p_vals[ i ];
      }
   }
   ~ArrayWrapper ()
   {
      delete [] _p_vals;
   }
private:
   int *_p_vals;
   int _size;
};

Notice that the copy constructor has to both allocate memory and copy every value from the array, one at a time! That’s a lot of work for a copy. Let’s add a move constructor and gain some massive efficiency.

class ArrayWrapper
{
public:
   // default constructor produces a moderately sized array
   ArrayWrapper () 
   : _p_vals( new int[ 64 ] ), _size( 64 )
   {}

   ArrayWrapper (int n) 
   : _p_vals( new int[ n ] ) , _size( n )
   {}

   // move constructor
   ArrayWrapper (ArrayWrapper&& other) 
   : _p_vals( other._p_vals  ) , _size( other._size )
   {
      other._p_vals = NULL;
   }

   // copy constructor
   ArrayWrapper (const ArrayWrapper& other) 
   : _p_vals( new int[ other._size  ] ), _size( other._size )
   {
      for ( int i = 0; i < _size; ++i )
      {
         _p_vals[ i ] = other._p_vals[ i ];
      }
   }
   ~ArrayWrapper ()
   {
      delete [] _p_vals;
   }

private:
   int *_p_vals;
   int _size;
};

Wow, the move constructor is actually simpler than the copy constructor! That’s quite a feat. The main things to notice are:

  1. The parameter is a non-const rvalue reference
  2. other._p_vals is set to NULL

The second observation explains the first–we couldn’t set other._p_vals to NULL if we’d taken a const rvalue reference. But why do we need to set other._p_vals = NULL? The reason is the destructor–when the temporary object goes out of scope, just like all other C++ objects, its destructor will run. When its destructor runs, it will free _p_vals. The same _p_vals that we just copied! If we don’t set other._p_vals to NULL, the move would not really be a move–it would just be a copy that introduces a crash later on once we start using freed memory. This is the whole point of a move constructor: to avoid a copy by changing the original, temporary object!

Again, the overload rules work such that the move constructor is called only for a temporary object–and only a temporary object that can be modified. One thing this means is that if you have a function that returns a const object, it will cause the copy constructor to run instead of the move constructor–so don’t write code like this:

const ArrayWrapper getArrayWrapper();

There’s still one more situation we haven’t discussed how to handle in a move constructor–when we have a field that is an object. For example, imagine that instead of having a size field, we had a metadata field that looked like this:

class MetaData
{
public:
   MetaData (int size, const std::string& name)
   : _name( name ), _size( size )
   {}

   // copy constructor
   MetaData (const MetaData& other)
   : _name( other._name ), _size( other._size )
   {}

   // move constructor
   MetaData (MetaData&& other)
   : _name( other._name ), _size( other._size )
   {}

   std::string getName () const { return _name; }
   int getSize () const { return _size; }
private:
   std::string _name;
   int _size;
};

Now our array can have a name and a size, so we might have to change the definition of ArrayWrapper like so:

class ArrayWrapper
{
public:
   // default constructor produces a moderately sized array
   ArrayWrapper ()
   : _p_vals( new int[ 64 ] ), _metadata( 64, "ArrayWrapper" )
   {}

   ArrayWrapper (int n)
   : _p_vals( new int[ n ] ), _metadata( n, "ArrayWrapper" )
   {}

   // move constructor
   ArrayWrapper (ArrayWrapper&& other)
   : _p_vals( other._p_vals  ), _metadata( other._metadata )
   {
      other._p_vals = NULL;
   }

   // copy constructor
   ArrayWrapper (const ArrayWrapper& other)
   : _p_vals( new int[ other._metadata.getSize() ] ), _metadata( other._metadata )
   {
      for ( int i = 0; i < _metadata.getSize(); ++i )
      {
         _p_vals[ i ] = other._p_vals[ i ];
      }
   }
   ~ArrayWrapper ()
   {
      delete [] _p_vals;
   }
private:
   int *_p_vals;
   MetaData _metadata;
};

Does this work? It seems very natural, doesn’t it, to just call the MetaData move constructor from within the move constructor for ArrayWrapper? The problem is that this just doesn’t work. The reason is simple: the value of other in the move constructor–it’s an rvalue reference. But an rvalue reference is not, in fact, an rvalue. It’s an lvalue, and so the copy constructor is called, not the move constructor. This is weird. I know–it’s confusing. Here’s the way to think about it. A rvalue is an expression that creates an object that is about to evaporate into thin air. It’s on its last legs in life–or about to fulfill its life purpose. Suddenly we pass the temporary to a move constructor, and it takes on new life in the new scope. In the context where the rvalue expression was evaluated, the temporary object really is over and done with. But in our constructor, the object has a name; it will be alive for the entire duration of our function. In other words, we might use the variable other more than once in the function, and the temporary object has a defined location that truly persists for the entire function. It’s an lvalue in the true sense of the term locator value, we can locate the object at a particular address that is stable for the entire duration of the function call. We might, in fact, want to use it later in the function. If a move constructor were called whenever we held an object in an rvalue reference, we might use a moved object, by accident!

// move constructor
ArrayWrapper (ArrayWrapper&& other)
: _p_vals( other._p_vals  ), _metadata( other._metadata )
{
   // if _metadata( other._metadata ) calls the move constructor, using
   // other._metadata here would be extremely dangerous!
   other._p_vals = NULL;
}

Put a final way: both lvalue and rvalue references are lvalue expressions. The difference is that an lvalue reference must be const to hold a reference to an rvalue, whereas an rvalue reference can always hold a reference to an rvalue. It’s like the difference between a pointer, and what is pointed to. The thing pointed-to came from an rvalue, but when we use rvalue reference itself, it results in an lvalue.

std::move

So what’s the trick to handling this case? We need to use std::move, from <utility>–std::move is a way of saying, “ok, honest to God I know I have an lvalue, but I want it to be an rvalue.” std::move does not, in and of itself, move anything; it just turns an lvalue into an rvalue, so that you can invoke the move constructor. Our code should look like this:

#include <utilityh> // for std::move

// move constructor
ArrayWrapper (ArrayWrapper&& other)
   : _p_vals( other._p_vals  ), _metadata( std::move( other._metadata ) )
{
   other._p_vals = NULL;
}

And of course we should really go back to MetaData and fix its own move constructor so that it uses std::move on the string it holds:

MetaData (MetaData&& other)
   : _name( std::move( other._name ) ) // oh, blissful efficiency
   : _size( other._size )
{}

Move assignment operator

Just as we have a move constructor, we should also have a move assignment operator. You can easily write one using the same techniques as for creating a move constructor.

Move constructors and implicitly generated constructors

As you know, in C++ when you declare any constructor, the compiler will no longer generate the default constructor for you. The same is true here: adding a move constructor to a class will require you to declare and define your own default constructor. On the other hand, declaring a move constructor does not prevent the compiler from providing an implicitly generated copy constructor, and declaring a move assignment operator does not inhibit the creation of a standard assignment operator.

How does std::move work

You might be wondering, how does one write a function like std::move? How do you get this magical property of transforming an rvalue reference into an lvalue reference? The answer, as you might guess, istypecasting. The actual declaration for std::move is somewhat more involved, but at its heart, it’s just astatic_castto an rvalue reference. This means, actually, that you don’t reallyneedto use move–but you should, since it’s much more clear what you mean. The fact that a cast is required is, by the way, a very good thing! It means that you cannot accidentally convert an lvalue into an rvalue, which would be dangerous since it might allow an accidental move to take place. You must explicitly use std::move (or a cast) to convert an lvalue into an rvalue reference, and an rvalue reference will never bind to an lvalue on its own.

Returning an explicit rvalue-reference from a function

Are there ever times where you should write a function that returns an rvalue reference? What does it mean to return an rvalue reference anyway? Aren’t functions that return objects by value already rvalues?

Let’s answer the second question first: returning an explicit rvalue reference is different than returning an object by value. Take the following simple example:

int x;

int getInt ()
{
   return x;
}

int && getRvalueInt ()
{
   // notice that it's fine to move a primitive type--remember, std::move is just a cast
   return std::move( x );
}

Clearly in the first case, despite the fact that getInt() is an rvalue, there is a copy of the variable x being made. We can even see this by writing a little helper function:

void printAddress (const int& v) // const ref to allow binding to rvalues
{
   cout << reinterpret_cast<const void*>( & v ) << endl;
}

printAddress( getInt() );
printAddress( x );

When you run this program, you’ll see that there are two separate values printed.

On the other hand,

printAddress( getRvalueInt() );
printAddress( x );

prints the same value because we are explicitly returning an rvalue here.

So returning an rvalue reference is a different thing than not returning an rvalue reference, but this difference manifests itself most noticeably if you have a pre-existing object you are returning instead of a temporary object created in the function (where the compiler is likely to eliminate the copy for you).

Now on to the question of whether you want to do this. The answer is: probably not. In most cases, it just makes it more likely that you’ll end up with a dangling reference (a case where the reference exists, but the temporary object that it refers to has been destroyed). The issue is quite similar to the danger of returning an lvalue reference–the referred-to object may no longer exist. Rvalue references cannot magically keep an object alive for you. Returning an rvalue reference would primarily make sense in very rare cases where you have a member function and need to return the result of calling std::move on a field of the class from that function–and how often are you going to do that?

Move semantics and the standard library

Going back to our original example–we were using a vector, and we don’t have control over the vector class and whether or not it has a move constructor or move assignment operator. Fortunately, the standards committee is wise, and move semantics has been added to the standard library. This means that you can now efficiently return vectors, maps, strings and whatever other standard library objects you want, taking full advantage of move semantics.

Moveable objects in STL containers

In fact, the standard library goes one step further. If you enable move semantics in your own objects by creating move assignment operators and move constructors, when you store those objects in a container, the STL will automatically use std::move, automatically taking advantage of move-enabled classes to eliminate inefficient copies.

References: http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html

Social media & sharing icons powered by UltimatelySocial