C++: Smart pointers, part 5: weak_ptr

This is the last of several posts I wrote related to smart pointers:

  1. Smart pointers
  2. unique_ptr
  3. More on unique_ptr
  4. shared_ptr
  5. weak_ptr

In modern C++ applications (C++11 and later), you can replace almost all your naked pointers to shared_ptr and unique_ptr in order to have automatic resource administration in a deterministic way so you will not need (almost, again) to release the memory manually.

The “almost” means that there is one scenario where the smart pointers, specifically, the shared_ptr instances, will not work: When you have circular references. In this scenario, since every shared_ptr is pointing to the other one, the memory will never be released.

Continue reading “C++: Smart pointers, part 5: weak_ptr”

C++: Smart pointers, part 4: shared_ptr

This is the fourth post of several posts I wrote related to smart pointers:

  1. Smart pointers
  2. unique_ptr
  3. More on unique_ptr
  4. shared_ptr
  5. weak_ptr

As I mentioned in other posts, C++11 brings a new set of smart pointers into C++. The most useful smart pointer is shared_ptr: Its memory management policy consists in counting the number of shared_ptr instances that refer to the same object in the heap.

Continue reading “C++: Smart pointers, part 4: shared_ptr”

C++: Smart pointers, part 3: More on unique_ptr

This is the third post of several posts I wrote related to smart pointers:

  1. Smart pointers
  2. unique_ptr
  3. More on unique_ptr
  4. shared_ptr
  5. weak_ptr

Ok, here I am going to write about two other features that unique_ptr has that I did not mention in my last post.

unique_ptr default behavior consists on take ownership of a pointer created with new and that would normally be released with delete.

Continue reading “C++: Smart pointers, part 3: More on unique_ptr”

C++11: std::future and std::async

C++11 introduces support for asynchronous calls in a very easy way.

An asynchronous call is a method invocation that will be executed in a separate thread (or core or processor); so, the caller of the method does not wait for the result of the execution and continue doing what is next; in this way, the compiler/processor/operating system can optimise the execution of the program and execute several routines at the same time (given the now common multicore systems we all have at home and in our pockets!). The standard library provides the mechanisms to perform those asynchronous calls and store the results until the caller will actually need them.

Continue reading “C++11: std::future and std::async”

C++11: std::thread

The standard library that ships with the new C++11 contains a set of classes to use threads. Before this, we needed to use the OS specific thread facilities each OS provides making our programs hard to port to other platforms.

Anyway, as today (November 16th, 2012), I tried threads using g++ 4.7 in Linux, Windows (through mingw), Mac and NetBSD and I just had success in Linux, Windows and Mac do not implement the thread features and NetBSD misses some details on the implementation (the this_thread::sleep_for() method, for example). Microsoft Visual Studio 2012 ships with good thread support.

To define a thread, we need to use the template class std::thread and we need to pass it a function pointer, a lambda expression or a functor. Look at this example:

Continue reading “C++11: std::thread”

C++11: enable_if

std::enable_if is another feature taken from the Boost C++ library that now ships with every C++11 compliant compiler.

As its name says, the template struct enable_if, enables a function only if a condition (passed as a type trait) is true; otherwise, the function is undefined. In this way, you can declare several “overloads” of a method and enable or disable them depending on some requirements you need. The nice part of this is that the disabled functions will not be part of your binary code because the compiler simply will ignore them.

Continue reading “C++11: enable_if”

C++11: unordered maps

The STL ships with a sorted map template class that is commonly implemented as a balanced binary tree.

The good thing on this is the fast search average time ( O(log2N) if implemented as a balanced binary tree, where N is the number of elements added into the map) and that when the map is iterated, the elements are retrieved following an established order.

C++11 introduces an unordered map implemented as a hash table. The good thing on this is the constant access time for each element ( O(1) ) but the bad things are that the elements are not retrieved in order and the memory print of the whole container can (I am just speculating here) be greater that the map’s one.

Continue reading “C++11: unordered maps”

C++: Variadic templates (functions)

A very interesting feature introduced in C++11 is called “variadic templates,” which, in short, are template classes and functions that can accept a variable number of parameterized types. They can be useful for several things, for example:

  • Providing type-safe replacements for functions with a variable number of arguments (stdarg.h).
  • Allowing the user to create instances of n-tuples.
  • Creating type-safe containers with elements of various types.

This post takes a look at variadic template functions.

For example, consider a function called show() that accepts any number of parameters and displays them separated by whitespace.

Thus, the following calls would be valid:

show(1, 2, 3); // that would output 1 2 3
show("Today is", dayOfTheWeek); // that would output "Today is Tuesday"
show(p1, p2, p3, p4, p5);

In plain old C, a function with a similar, though not identical, signature could be implemented using the variable argument functions mechanism provided by C, along with the functions, types, and macros defined in the stdarg.h library. However, there are two problems with that approach:

  1. The number of arguments must be provided explicitly or implicitly. A good example of this is the C printf function. When declaring its signature, the number of format specifiers used implicitly defines the number of parameters that need to be accessed. For example, printf("%d %s", a, b); knows that there are two variables, and printf("%d %d %d", x, y, z); knows that there are three.
  2. The function is not type-safe in the sense that the programmer is responsible for determining the type of each variadic argument (that’s what the “%s” or “%d” in printf are used for).
void show(int n, ...)
{
    va_list x;
    va_start(x, n);
    for (int i = 0; i < n; i++)
    {
      // retrieve the parameter with va_arg and show it. There is no type info here.
    }

    va_end(x);
}

With the example above, since the type of each parameter after n is not specified, the supported types should be documented somehow; otherwise, the behavior will not be deterministic.

Before C++11, there were two partial solutions to this problem: one would be to create several overloaded functions, similar to this implementation:

template <typename T1>
void show(const T1& t1)
{
  std::cout << t1 << std::endl;
}

template <typename T1, typename T2>
void show(const T1& t1, const T2& t2)
{
  std::cout << t1 << " " << t2 << std::endl;
}

template <typename T1, typename T2, typename T3>
void show(const T1& t1, const T2& t2, const T3& t3)
{
  std::cout << t1 << " " << t2 << " "  << t3 << std::endl;
}

… and so on.

The other solution would be to have a base class (similar to the Java object model) and implement a method similar to this one:

void show(const Object* o1, const Object* o2 = nullptr, const Object* o3 = nullptr, const Object* o4 = nullptr, const Object* o5 = nullptr, const Object* o6 = nullptr)
{
  std::cout << o1->toString() << " ";
  if (o2)
      std::cout << o2->toString() << " ";
  if (o3)
    std::cout << o3->toString() << " ";
  if (o4)
    std::cout << o4->toString() << " ";
  if (o5)
    std::cout << o5->toString() << " ";
  if (o6)
    std::cout << o6->toString() << " ";

  std::cout << std::endl;
}

Though they would work, both approaches have their weaknesses. Both will support only a fixed number of arguments. In the first implementation, the programmer must provide N overloads to support N parameters, and in the second implementation, the programmer must provide a class hierarchy to make it work.

Variadic templates perform a type expansion similar to the template-based implementation (my first solution above), but this is done by the compiler instead of the programmer.

What is interesting about such expansion is that it is performed recursively.

This code implements the show function using variadic templates:

template <typename T>
void show(const T& value)
{
  std::cout << value << std::endl;
}

template <typename U, typename... T>
void show(const U& head, const T&... tail)
{
   std::cout << head << " ";
   show(tail...);
}

The first overload will be the base case, where either a single parameter is passed to the show() method or when all the other overloads have already been expanded.

The second overload is very interesting because we declare a function that takes two elements: U and T. U represents a concrete type (the type of the element to be actually printed), while T represents a list of types (notice the ... syntax). The argument list of the function is also interesting: head will be a const reference to a value of type U, and ...tail will represent a set of const references to several types.

Now, look at the implementation. We take the head and display it using std::cout, and then invoke another overload of show() by passing the tail list of parameters The tail... syntax is called parameter pack expansion, and it is similar to taking all the arguments that tail represents and “expanding” them as individual parameters in the function call. At this point, if the list of parameters contains more than one type, the compiler will create a new overload for this method. If the list of parameters contains only one type, the compiler will invoke the first overload already defined.

Amazing, isn’t it?

This feature is heavily used in variadic template-based classes in the Standard Library, such as std::C++11: std::tuple and C++17: std::variant.