Author Archives: Marius Bancila

About Marius Bancila

Co-fondator CODEXPERT Microsoft MVP VC++

The standard way of converting between numbers and strings in C++11

In C++03 there was no standard way of converting numbers to strings. The best way to do that was using a std::stringstream:

One could put that into a more generic function that looks like this:

The opposite of converting a text to a number could look like this:

Of course, there was also the option of using C functions such as itoa, sprintf or atoi (or their Microsoft secure version _itoa_s, sprintf_s).

C++11 provides several standard functions for converting numbers to strings and strings to numbers, all of them available in the <string> header.

For converting numbers to strings there are two new overloaded functions: to_string() and to_wstring(). They take one argument of various numeric types (int, long, long long, double, long double, etc.) and return either a std::string or a std::wstring with the number converted to text.

These functions are actually just wrappers over sprintf and swprintf. According to the standard (section 21.5):

Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of “%d”, “%u”, “%ld”, “%lu”, “%lld”, “%llu”, “%f”, “%f”, or “%Lf”, respectively, where buf designates an internal character buffer of sufficient size.

For the other way around of converting strings to numbers there are several overloaded methods (taking either a std::string or a std::wstring):

  • stoi: converts a string to a signed integer
  • stol: converts a string to a signed long
  • stoll: converts a string to a signed long long
  • stoul: converts a string to an unsigned long
  • stoull: converts a string to an unsigned long long
  • stof: converts a string to a float
  • stod: converts a string to a double
  • stold: converts a string to a long double

Functions stof, stod and stold are also just wrappers over strtod and strtold:

the first two functions call strtod(str.c_str(), ptr) and the third function calls strtold(str.c_str(), ptr). Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

atoi() and atol() that convert a null-terminated byte-string (i.e. char*) to an integer or long were already available in header <cstdlib>. There is a new function available in this header called atoll() that converts a null-terminated byte string to a long long value.

Assigning algorithms in the C++ Standard Library

The C++ Standard Library provides several algorithms for assigning values to a range (such as a container or a C-array).

fill and fill_n

std::fill assigns a given value to all the elements in a range. It is available in the header <algorithm>. In the following example all elements of a vector of integers are assigned the value 1.

std::fill_n is similar, but instead taking the bounds of a range it takes the beginning and a count and initializes N elements starting from the specified first element. You must make sure that first + count does not exceed the bounds of the range. The following example is an equivalent of the first:

generate and generate_n

These algorithms are similar to the first, but instead of taking a value to assign they take a function and assign the value returned by the function. They are also available in the header <algorithm>.

std::generate assigns the elements in a range the values returned by a function.

In the following example we initialize a vector of 10 elements with random numbers (using a Marsenne twister engine).

The result may look like this:

You can use lambdas as the function whose return value is stored into the range. The following example generates random numbers ranging from 1 to 100 with a uniform distribution.

Result may look like this:

std::generate_n is similar, but instead of taking the limits of the range it takes the beginning and a count and assigns the first N values returned by the function to the range. You must makes sure that first + count does not exceeds the bounds of the range.

In the following example we initialize the elements of a vector with values from 1 to N, where N is the size of the range.

The result is:

iota

std::iota is a new algorithm to C++11. It assigns the elements of a range with sequentially increasing values starting from a given value. The algorithm is available in header <numeric>.

The following example initializes the elements of a vector with values from 1 to N, where N is the size of the range (basically the same thing we did in the last example).

The result is:

Notice that the term iota is taken from the APL programming language and denotes the Greek letter used in various mathematical notations.

Function return type deduction in C++14

C++11 introduced the auto keyword as a placeholder for types. It could be used for declaring variables but also for the return type of a function, given than you use a new syntax with a trailing type at the end of the function.

or

This is a bit cumbersome and too explicit so C++14 takes the next step and makes the trailing return type unnecessary. Under C++14 the above examples can be simply written as:

and

There are several things to keep in mind:

  • if a function has more than one return statement they all must deduce the same type
  • a recursive function can have an auto return type only if it has a non-recursive return statement before the recursive call.
  • a function with an auto return type can be forward declared, but cannot be used until it has been defined

In my personal opinion auto return type should be used with caution. It can make the code harder to read and maintain (you don’t know the type just by looking at the signature), harder to document (automatic documenting tools use the signature to produce documentation), and can lead to situations when the developer expects one return type but the compiler generates another.

Additional readings:

Inherited constructors in C++11

In C++, a function in a derived class with the same name as one (or a set of overloads) in a base class, hides the function (or the overloads) from the base class. Here is an example:

As the comments show, calls to foo() and foo(42, 3.14) trigger compiler errors. The call to foo(42) is all right because there is an implicit conversion from int to double.

It is possible to “un-hide” the functions from the base class with a using directive.

The code in main will now compile and the program will output:

A limitation of this feature was that it didn’t work with constructors. In other words the following is failing to compile.

This can be achieved by writing a matching constructor in the derived for every constructor in base.

However, when you have hierarchies with many derives and you have to provide one or more constructors like this just to call the right constructor of base it becomes annoying.

A solution to the problem is provided by C++ 11. The using directive now works also for constructors. The derived class in the last example is semantically equivalent to

This code will produce the following output:

Keep in mind that the lifted constructors are simply calling the base constructors and do not perform any member initialization. Suppose you had some member like in the following example:

Regardless what constructor is used to create the object, value will remain uninitialized. To avoid that you have two options:

  • don’t use the using directive to lift the constructors from base and write the constructors for the derived class explicitly
  • initialize the member variables explicitly (using non-static data member initializers):

Availability. At the time of writing this post, inherited constructors are supported by g++ 4.8 and clang 3.3. Visual Studio does not support it and is not known in which version in the future it will. Non-static data member initializers are supported by Visual Studio 2013 RTM, g++ 4.7 and clang 3.0.

Farewell to new and delete

C++11 introduced several smart pointers (residing in the <memory> header):

  • std::shared_ptr: retains shared ownership of an object, that is destroyed when the last shared_ptr that holds a reference to it is destroyed or assigned another pointer.
  • std::unique_ptr: retains sole ownership of an object, that is destroyed when the unique_ptr goes out of scope
  • std::weak_ptr: retains a non-owning reference to an object managed by a shared_ptr. It does not participate in the reference counter of the shared pointer. It is mainly use to break circular dependencies.

While these smart pointers manage resources automatically, so there is no need to delete object explicitly, they still require explicit instantiation with new for the managed resource.

C++11 introduced std::make_shared, a free function that constructs an object and wraps it in a std::shared_ptr object.

C++14 introduces another free function, std::make_unique, that constructs an object and wraps it in a std::unique_ptr object.

With these smart pointer and functions available there is no need any more to use new and delete in your C++ code. Besides avoiding explicit allocation and release these functions have another important advantage: they prevent memory leaks that could happen in the context of function calls. You can read Herb Sutter’s GotW #102: Exception-Safe Function Calls for details about this problem.

C++11 concurrency: locks revisited

In a previous post about locks in C++11 I have shown a dummy implementation of a container class that looked like this (simplified):

One can argue that the dump() method does not alter the state of the container and should be (logically) const. However, as soon as you make it const you get the following error:

‘std::lock_guard<_Mutex>::lock_guard(_Mutex &)’ : cannot convert parameter 1 from ‘const std::recursive_mutex’ to ‘std::recursive_mutex &’

The mutex (regardless which of the four flavors available in C++11) must be acquired and released and the lock() and unlock() operations are not constant. So the argument the lock_guard takes cannot be logically const, as it would be if the method was const.

The solution to this problem is to make the mutex mutable. Mutable allows changing state from const functions. It should however be used only for hidden or “meta” state (imagine caching computed or looked-up data so a next call can complete immediately, or altering bits like a mutex that only complement the actual state of an object).

An important thing to note is that in C++11 both const and mutable imply thread-safety. I recommend this C++ and Beyond talk by Herb Sutter called You don’t know [blank] and [blank].

C++11 concurrency: condition variables

In the previous post in this series we have seen the C++11 support for locks and in this post we continue on this topic with condition variables. A condition variable is a synchronization primitive that enables blocking of one or more threads until either a notification is received from another thread or a timeout or a spurious wake-up occurs.

There are two implementations of a condition variable that are provided by C++11:

  • condition_variable: requires any thread that wants to wait on it to acquire a std::unique_lock first.
  • condition_variable_any: is a more general implementation that works with any type that satisfies the condition of a basic lock (basically has a lock() and unlock() method). This might be more expensive to use (in terms of performance and operating system resources), therefore it should be preferred only if the additional flexibility it provides is necessary.

So how does a condition variable work?

  • There must be at least one thread that is waiting for a condition to become true. The waiting thread must first acquire a unique_lock. This lock is passed to the wait() method, that releases the mutex and suspends the thread until the condition variable is signaled. When that happens the thread is awaken and the lock is re-acquired.
  • There must be at least one thread that is signaling that a condition becomes true. The signaling can be done with notify_one() which unblocks one thread (any) that is waiting for the condition to be signaled or with notify_all which unblocks all the threads that are waiting for the condition.
  • Because of some complications in making the condition wake-up completely predictable on multiprocessor systems, spurious wake-ups can occur. That means a thread is awaken even if nobody signaled the condition variable. Therefore it is necessary to check if the condition is still true after the thread has awaken. And since spurious wake-ups can occur multiple times, that check must be done in a loop.

The code below shows an example of using a condition variable to synchronize threads: several “worker” threads may produce an error during their work and they put the error code in a queue. A “logger” thread processes these error codes, by getting them from the queue and printing them. The workers signal the logger when an error occurred. The logger is waiting on the condition variable to be signaled. To avoid spurious wakeups the wait happens in a loop where a boolean condition is checked.

Running this code produce an output that looks like this (notice this output is different with each run because each worker thread works, i.e. sleeps, for a random interval):

The wait() method seen above has two overloads:

  • one that only takes a unique_lock; this one releases the lock, blocks the thread and adds it to the queue of threads that are waiting on this condition variable; the thread wakes up when the the condition variable is signaled or when a spurious wakeup occurs. When any of those happen, the lock is reacquired and the function returns.
  • one that in addition to the unique_lock also takes a predicate that is used to loop until it returns false; this overload may be used to avoid spurious wakeups. It is basically equivalent to:

As a result the use of the boolean flag g_notified in the example above can be avoided by using the wait overload that takes a predicate that verifies the state of the queue (empty or not):

In addition to this wait() overloaded method there are two more waiting methods, both with similar overloads that take a predicate to avoid spurious wake-ups:

  • wait_for: blocks the thread until the condition variable is signaled or the specified timeout occurred.
  • wait_until: blocks the thread until the condition variable is signaled or the specified moment in time was reached.

The overload without a predicate of these two functions returns a cv_status that indicates whether a timeout occurred or the wake-up happened because the condition variable was signaled or because of a spurious wake-up.

The standard also provides a function called notified_all_at_thread_exit that implements a mechanism to notify other threads that a given thread has finished, including destroying all thread_local objects. This was introduced because waiting on threads with other mechanisms than join() could lead to incorrect and fatal behavior when thread_locals were used, since their destructors could have been called even after the waiting thread resumed and possible also finished (see N3070 and N2880 for more). Typically, a call to this function must happen just before the thread exists.

Below is an example of how notify_all_at_thread_exit can be used together with a condition_variable to synchronize two threads:

That would output either (if the worker finishes work before main)

or (if the main finishes work before the worker):