Journal

2011-06-28 CPlusPlus0X

Taking initialization one step further - Uniform Initialization

Initializing containers is fine but what about structs or classes. Well in good old C++ some initialization was possible using the brace notation. In C++2011 that is taken further by making the initialization uniform and work on any object. So if you have a class with a constructor

class Person
{
public:
  Person(const string & name, int age)
  : name_{name}, age_{age} {};
...
private:
  string name_;
  int age_;
};

you can initialize it like this:

Person me{"No Name", 50};

The same syntax as for a vector or a list but this time for class with a constructor taking two arguments, a string and an int. This works for structs with no constructor as well just initializing each member as you would expect.

You can even do this. Note how the return statement just contains the initialization of the Person type.

Person getPerson()
{
  return {"Foo Bar", 42};
}

2011-06-27 CPlusPlus0X

Initializer lists

How many times have you not wanted to easily initialize a container with a list of values. Instead you would have to solve that with repeated push_backs either inline or in a loop over a good old C array that could be initialized with the brace notation. C++2011 now fixes this by introducing the initializer_list-template.

It works like this. Constructors and a other functions can take a parameter of type std::intitializer_list:

void function(initializer_list<string> list) 
{ 
   cout << "Number of args are " << list.size() << endl; 
   for (auto it = list.begin(); it != list.end(); ++it) 
   { 
      cout << "List contains: " << (*it) << endl; 
   } 
} 

You can call function like this:

   function({"hi", "ho", "foo", "bar"});

The standard library classes implements this so we can now initialize a vector of strings with either of these ways:

   vector<string> v1 = {"hi", "ho", "foo", "bar"}; 
   vector<string> v2 {"hi", "ho", "foo", "bar"}; 

So this adds yet another feature that makes C++ just a little more convenient to use, easier on the typing and makes the code cleaner and easier to understand.

2011-06-17 CPlusPlus0X

More on type inference

Together with auto there is a new keyword decltype. It is used to determine the type of an expression in compile time. You can do like this:

auto var1 = 3.14;
decltype(var1) var2;

var2 will get the same type as var1. Who in it its turn got its type from the initialization with 3.14 and so they are both doubles.

Right now it might not be entirely obvious what this is good for, and it is probably of most use for library developers, but now you have seen it anyway.

2010-11-19 CPlusPlus0X

OOPS! Other stuff came along and I have had to stop with learning more about the new features in C++. I'll try to plan for doing this so that it actually will happen. Stay tuned.

2010-08-06 CPlusPlus0X

As it happens I have had a long vacation and done other stuff than thinking about the new standard. That is probably a good thing. Soon there is time for work and hopefully I will get some time then to come back to these matters.

2010-06-19 CPlusPlus0X

Auto is dead, long live auto

The keyword auto will get a new meaning. The old meaning is something you might not remember because in practice it was used very little. This was because it was the default so it could be left out and it normally was.

The new meaning is of more interest. Auto means that the type of a variable is deduced from its initializer expression. This can be as simple as

auto i = 1;

where the type of i will be int.

Of more practical use is when the initializer expression is more complex. Take for example the initialization of the loop variable in a for loop when traversing a standard library container. The loop variable takes the type of an iterator over the container. That was hard to write before but can now be written like this:

for (auto it = l.begin(); it != l.end(); ++it)
{
...;
}

2010-06-18 CPlusPlus0X

Getting a tool chain to experiment with

To experiment with the new C++ features it is good to have a tool chain so that you can see whether your code is OK. It is fun to write code but it is even better when you can run it!

Fortunately we have gcc. Unfortunately the support for the upcoming standard isn't in the stable releases. It wouldn't be an upcoming standard if it was I guess. So we need to get a development version. That isn't so hard to do (if you are on a linux/unix system that is)

The gcc development version can be downloaded. It is under version control using subversion. So it can be checked out. This way it is easy to update when the developers off gcc adds new features. Check it out like this:

svn checkout svn://gcc.gnu.org/svn/gcc/trunk <your-working-dir>

After that it is actually just a matter of running configure and make. I choose to set the prefix to my $HOME so that it would not mess with stable release of gcc I use for normal work. This installation is just for trying out the new features. So cd to your <your-working-dir> and follow the install instructions there. Configuring the build should be as easy as creating a build directory and doing

../configure --prefix=$HOME --enable-languages=c++

and building it should need no more than...

make
make install

should do it. gcc is then available in $HOME/bin. Voilá, we are read for trying out some code. Just one last thing to look out for. The new features are not activated by default in the beta version of gcc. So in order to use them we need to explicitly tell the compiler we want the new features. You can do like this:

$HOME/bin/gcc -static -std=c++0x

I have added the flag -static there as well to get statically linked executables. This way we avoid having to bother about dynamic linkage when running the programs. Remember we are using a version of gcc where the libraries are not installed in the standard location.