CPlusPlus11

Time flies. That once was an interesting upgrade and modernization of the good old C++ has since turned into an ongoing effort. I have since a few years left active C++ development so these pages are left as they were when C++11 was the next big thing. Maybe some of the articles are still usable. Enjoy!


Well the standard is here already but my pages were named CPlusPlus0X. So I better start writing under this new label CPlusPlus11 in order to seem some what up to date.

These are the sources to info about C++11 I have used so far:

Below follows the blog which means the order can be far from pedagogic in fact it is in reverse pedagogic order! See CPlusPlusArticles for all blog posts ordered by date.

2014-11-22 CPlusPlus11

Digit Separators

When I talked about the binary literals recently I also mentioned digit separators. I thought it was part of C++0x but apparently it is also a new C++1y feature that I have not mentioned yet. Sorry for that. There are so many features so I'm getting confused. ;-) Time to change that then.

Anyway, digit separators is a way to write big numbers so they are easier to read for humans. The apostrophe character is what is used to group or separate digits in a number. It can look like this:

   int decimal = 4'096;
   int binary = 0b0001'0000'0000'0000;
   int hexadecimal = 0x10'00;
   int octal = 0'10'000;
   double x = 1.234'567'890e-19;

Look how the apostrophe neatly groups the digits in the way we are use to see them.

The position of the apostrophe can however be anywhere in the number. It does not have to be according to the radix or any other normal way numbers are written out there in real life. It can be used in any way you like. The later is probably a bad idea but, who knows, there might be cases where it can be put to good use.

2014-11-17 CPlusPlus11

Binary Literals

One tiny(!?) extension that comes with C++14 is binary literals. You can now write them by prefixing the binary number with 0b. This is a well known syntax from other languages and in fact has been around a while even as a gcc extension. So you might not even recognize this as new feature.

Anyway, it looks like this:

   int b1 = 0b10;
   int b2 = 0B1010;     // Capital B is OK too!

It goes well with digit separators too. You can write:

   int b3 = 0b1010'1010;
   int b4 = 0B010'101'010;

2014-11-12 CPlusPlus11

The deprecated attribute

To mark an entity as deprecated the attribute deprecated is introduced. The idea is to be able to mark things, although they are still working, that their use are being discouraged for some reason. The thought goes to things that will be removed in future releases but it is of course not limited to that.

This is different to most other C++-1y features a compile time only feature. It will produce a warning when the code is compiled. That is it.

The syntax is like this:

[[deprecated]]
int func(int i)
{
   ...

You can even add an explanation to why this function is deprecated and this string will be shown in the warning message by the compiler.

[[deprecated("Don't use this please, we are going to remove this next release or so")]]
int old(int i)
{
   ...

Most entities can be marked as deprecated this way. Here are some examples.

class [[deprecated]] C
{
   ...

class C2
{
public:
   [[deprecated]]
   int func(...
   ...

2013-04-29 CPlusPlus11

C++1y/C++14

Just when you have been starting to wonder when all these nice C++11 features are going to get to the compiler you use in your day job the standardization moves on with C++1y/C++14! For the status of gcc look here. It really seem like the polishing of C++ to make it a modern language has been a positive experience. So now it is time to look into the new C++1y features!

2012-10-10 CPlusPlus11

Template-ized typedefs and template Aliases

With C++11 we can define a typedef as a template using the keyword using. Suppose you have a type with the template type parameter T and the template int parameter size. Now typedefs can't be templates but with the new using syntax the type can be defined like this:

template<typename T, int size>
using TheType = array<T, size>;

Achieving the same result as typedef. Now we have a type, TheType?, that is a template type.

It does not end there. We can further partially bind a template using the same syntax. So if we would like to define a new type based on TheType? but with the size bound to 10 we would do like this:

template <typename T>
using SizeTen = TheType<T, 10>;

2012-06-15 CPlusPlus11

Raw String Literals

A raw string is a character sequence where there are no special characters. What you see is what you get. This makes it much easier to defined a string that contains a character sequence that would be interpreted as a special char if a normal string would have been used. Sequences like \n, \t, \b etc needs special treatment if not to be interpreted as special characters.

The syntax in its most straight forward form is this:

R"(<char-sequence>)"

R for raw and "( and )" as starting and ending sequence allowing characters between be just what they are. Here are some examples of raw strings:

R"(hello "world")"               -> hello "world"
R"(no newline \n or tab \t)"     -> no newline \n or tab \t

R"(
Multiline "string"
          is just as it is typed
)"                               -> Multiline "string"
                                              is just as it is typed

As seen in the last example you can easily define large multilined text this way.

Another situation where raw strings pay off is when there are lots of chars that normally needs to be escaped. This is the situation with regular expressions where the back slash character, \, is used either to give or remove special meaning to characters. So in regular expressions defined by normal strings the back slash character itself needs to be escaped. We don't need all this extra escaping when using raw strings.

Regexp support isn't in gcc yet so I'll come back with examples later.

To complete the definition of raw strings. What if you need the terminating sequence )" in your raw string? The general definition of a raw string, which allows you to specify a delimiter sequence, solves this:

R"<delimiter>(<char-sequence>)<delimiter>"

Where delimiter is an up to 16 char sequence with no whitespace. So you can write like this using # as delimeter:

R"#(')"')#" -> ')"'

2012-05-11 CPlusPlus11

Unrestricted Unions

Unions is somewhat of a white area on the C++ map for me. I can't remember that I have ever used a union in a C++ program. Nevertheless C++11 have introduced a way to improve unions.

What it is all about is that before C++11 unions could not have members that had non-trival constructors. So if you had a union like this

   union U
   {
      int i;
      Class c;
   };

and class Class had a non-trivial constructor, it would be illegal. In C++11 this restriction is lifted and the code is legal.

2012-05-09 CPlusPlus11

The future of threading

A major concern these days is how to handle all these cores we have available everywhere. How to program them? C++11 tries to address this problem by including support for threads in the standard library.

The basic stuff for starting and joining threads and synchronization with the help of different types of mutexes is there. Support for low level atomic operations is there to. We might come back to those issues later. Now we will look at the high level support provided by futures and async.

The basic functionality is this. The function async takes nearly anything executable and returns a future object. When you want to have the result from the async call you call the get method on the future object.

   auto f = async(doIt);
   ...
   auto resultFromDoIt = f.get();

Very simple in its basic form. But there is more...

The async execution can be controlled in more detail by specifying a launch policy. It can be launched either async or deferred. If it is called with async policy it will be started asynchronously if it can. You'll get an exception otherwise.

   auto f = async(launch::async, doIt);

When launch::deferred is used it is guaranteed that the function wont run until get is called. What good this is for is another question. Debugging could be one use of it.

Besides the get method there are also methods to poll for a result.

I also said async could be called with almost anything that could be executed. It can take functions, member functions and lambdas. You can pass arguments to the functions.

Be careful though when passing arguments so that they don't go out of scope before the asynchronous computation is finished. All these types of problems are of course still relevant for asynch. Passing arguments by value is one solution to that problem.

2012-05-08 CPlusPlus11

Still moving on

One obvious place for moving objects instead of copying is when making a swap. It is a common operation so there is even a library function for that, std::swap. When used with types that implements the move-ctor and move assignment operator it looks like this.

First we define the move members to illustrate our example.

   ...
   Class(Class&& c) { cout << "Class&& ctor" << endl; }
   Class& operator=(Class&& c) { cout << "Class&& operator=" << endl; return *this; }
   ...

Running this code

   Class c1;
   Class c2;
   swap(c1, c2);

Produces this output:

   Class&& ctor
   Class&& operator=
   Class&& operator=

This tells us that first one of the objects is moved somewhere. A temporary lvalue to hold the value as party of the swap. Then there are two move assignments to get the values back in their new place.

If we would implement this ourselves it could look like this:

   Class temp(move(c1));
   c1 = move(c2);
   c2 = move(temp);

This introduces the new function std::move. It can look a little strange but its job is no more and no less than to typecast its argument into an rvalue reference. This will enable the use of the move members and the output is the same as the example above.

The move feature has been implemented in the standard library containers. So code like this:

   vector <Class> v;
   v.push_back(Class());

will use the move ctor when the new Class object is pushed into the vector. This was legal code before C++11 so this is an example where old code will benefit from the new features without any changes.

2012-05-08-1 CPlusPlus11

Changes to old habits - you need to move to!

With moving available the old habit of always passing non native types as const to ref is not necessary any more. Moving makes call by value and return by value good alternatives.

From my experience return by value was something that was used a lot although the overhead of a copy. Partly because functions are easier to understand that way, return values in parameters is not taught as a good design, and partly because of the return value optimization sometimes got away without a copy anyway and still do!

With C++11 we can safely use call by value when we want that even for complex types. So we should write code like this from now on:

   string manipulate(string s)
   {
      <... perform some manipulation on s ...>
      return s;
   }

Since we are going to change the value on the string we might as well use call by value and change that. The modified value is then returned. The move ctor will kick in an see to that no unnecessary copy is needed.

More...