Cool C++0X features

Index

  1. Cool C++0X features 1: Intro
  2. Cool C++0X features 2, Variadic templates: What's wrong with varargs
  3. Cool C++0X features 3: Variadic templates, a fix for varargs
  4. Cool C++0X features 4: Variadic templates again
  5. Cool C++0X features 5: Templates and angle brackets, a short interlude
  6. Cool C++0X features 6: A variadic wrapper
  7. Cool C++0X features 7: A variadic wrapper solution
  8. Cool C++0X features 8: Variadic wrapper and type inference with decltype
  9. Cool C++0X features 9: delayed type declaration
  10. Cool C++0X features 10: type inference with decltype
  11. Cool C++0X features 11: decltype and disappearing constness
  12. Cool C++0X features 12: type inference with auto
  13. Cool C++0X features 13: auto and ranged for, cleaner loops FTW
  14. Cool C++0X features 14: Initializer lists
  15. Cool C++0X features 15: Initializer lists for custom (non-std) objects
  16. Cool C++0X features 16: Lambdas
  17. Cool C++0X features 17: Lambdas syntax

Cool C++0X features I: Intro

Published 2011-04-18

C++0X brings some very cool changes, and I wanted to start a series of posts regarding some of these changes, with a small explanation of each new feature (that I currently understand, at least), an example of its usage and why I think it's a cool thing. Notice these two may be mutually exclusive, some of these may just be cool but I wouldn't recommend using them on a day to day basis. An example of a very cool feature which I wouldn't normally use in a project is the one I want to write about today: variadic templates.

What's not to love about variadic templates? Its name implies (correctly) that it uses templates, and it also has a "variadic" thingy, which you can use to look smart since no one really knows what it means.

Templates themselves can quickly get complicated if used by unexperienced padawans in the art of martial C++, yet their hypnotic beauty draws every programmer to use them just like flies are drawn to fire. When used correctly they can produce very elegant code; if not for the template programmer, at least for the end user. Yet in all their power, templates in C++ have been lacking a fundamental aspect: a variable number of arguments.

There are ways to work around this limitation, like using a list of types paired with a template-paramlist-object. Sounds familiar? (I know it doesn't, don't worry). You could also generate N constructors, one overload for each parameter count. The drawback, exponential compile time (say, TR1). These are all hacks, which are in place only because there wasn't a safe way of passing a list of types associated with a list of arguments. This is over now with variadic templates in C++0X.

So, what kind of problem would variadic templates solve? Let's name a few: * A typesafe varargs function (a function with a variable number of arguments) * Easily create a template object which acts as a tuple * An easier implementation of a reduce (inject) function

This entry is getting quite long so we'll start seeing these examples on the next post.

Cool C++0X features II, Variadic templates: What's wrong with varargs

Published 2011-04-19

Last time we explained what variadic templates are. We'll see what they can do now. We mentioned that solving the problem of having a type-safe varargs is one of the best ways of applying variadic templates, but what's varargs?

Varargs functions (from C world, not even from C++!) are functions which have a variable number of arguments, just like printf. These are usually very dangerous functions, since they are not typesafe. Let's see how they are implemented with an example:

#include 
#include 
// My god, it's full of bugs
void va_println(int args_left, ...) {
   va_list arg_lst;
   va_start(arg_lst, args_left);
   while(args_left--) {
      const char p = va_arg(arg_lst, const char);
      std::cout << p;
   }
   va_end(arg_lst);
}
int main() {
   va_println(3, "Hola ", "mundo", "n");
   return 0;
}

This implementation of a function with variable arguments is, more or less, the best C can give us, yet it riddled with bugs and hidden problems. Let's go one by one:

#include 
struct X { virtual ~X(){} };
void va_println(int args_left, ...) {
   va_list arg_lst;
   va_start(arg_lst, args_left);
   while(args_left--) {
      X p = va_arg(arg_lst, X);
   }
   va_end(arg_lst);
}
int main() {
   X x, y, z;
   va_println(3, x, y, z);
   return 0;
}

And how do we fix it?

The fix is easy. Too easy. You just need C++0X. We will discuss why this is better next time, but just as a sneak peak:

void println() {}
template  void println(H p, T... t) {
   std::cout << p;
   println(t...);
}
int main() {
   println("Hola", " mundo ", 42, 'n');
   return 0;
}

Remember to compile using -std=c++0x in gcc.

(Thanks Hugo Arregui for correcting the POD example)

Cool C++0X features III: Variadic templates, a fix for varargs

Published 2011-04-26

Last time we saw why a function with varargs may bring lots of problems. Then we saw how to solve it, but never explained why that last solution doesn't have the problems the varargs solution had, nor how does it work. Let's start by copying the solution here:

// Stop condition
void println() {}
// General case
template 
void println(H p, T... t)
{
   std::cout << p;
   println(t...);
}
int main() {
   println("Hola", " mundo ", 42, 'n';);
   return 0;
}

It certainly looks much better than the varargs function, even though some new strange syntax has been introduced. Keep in mind some template-foo is required, not only because of the syntax but because we'll be talking about functional programming too.

With all that intro (the last 2 articles were just an intro!) now we are in a good shape to ask what a variadic template really is. In its easiest form, it's just a list of template arguments, like this:

template  void foo(T... t) {}

That simple template can accept as many parameters as you need, of any type. This is much safer than a vararg because:

Pretty neat, huh? But how does it work? Variadic templates are actually very similar to how Haskell handles lists, you get all the arguments as a list of types in which you can either get the head or the tail. To do something useful, get the head and continue processing the tail recursively.

template 
void do_something(H h, T... t)
{
    // Do something useful with h
    really_do_something(h);
    // Continue processing the tail
    do_something(t...);
}

Of course, you'll eventually need a condition to stop processing: (we'll explain the new syntax later)

void do_something()
{
    // Do nothing :)
}

When the list is completely processed the empty do_something function will be called. Easy, right? But it does have a lot of weird syntax. Let's see what each of those ellipses mean:

With all that in mind, let's put together our typesafe printf:

// Condition to stop processing
void println() {}
// Println receives a list of arguments. We don't know it's type nor
// how many there are, so we just get the head and expand the rest
template 
void println(H p, T... t)
{
    // Do something useful with the head
    std::cout << p;
    // Expand the rest (pass it recursively to println)
    println(t...);
}
int main() {
    // See how it works even better than varargs?
   println("Hola", " mundo ", 42, 'n');
   return 0;
}

Next time, we'll see a more complex (and fun) example of variadic templates.

Cool C++0X features IV: Variadic templates again

Published 2011-05-03

Last time we finally solved the varargs problem. Let's review what we learned: * Variadic templates let us create something receiving a variable set of arguments * We can process the head of that set, then recursively process the tail * It adds weird new syntax + When declaring typename... T you are saying "here goes a list of types" + When declaring T... t you are saying t is a list of objects with different type + When you write t..., you are saying "expand the list of arguments" * It's type safe * It's very neat to confuse your coworkers

So, what can we do with it besides implementing our own version of printf? Let's do something better, let's try adding up a list of numbers to start flexing our variadic templatefooness (?).

What's the usual way of adding a list of numbers? In templates, that is. We need something like this:

sum (H:T) <- H + sum(T)
sum () <- 0

Of course, in C++ templates you don't have values, you just have types. We could implement it like this (if this looks like a new language you may want to check my template metaprogramming series):

#include 
struct Nil{};
template  struct Lst {
    typedef H Head;
    typedef T Tail;
};
template <
        template class Op,
        typename Head,
        typename Lst>
struct intForeach
{
    typedef typename intForeach
        < Op, typename Lst::Head, typename Lst::Tail >::result Next;
    typedef typename Op< Head, Next >::result result;
};
template <
        template class Op,
        typename Head>
struct intForeach 
{
    typedef Head result;
};
template <
        typename Lst,
        template
        class Op>
struct Reduce
{
    typedef typename intForeach
        < Op, typename Lst::Head, typename Lst::Tail >::result result;
};
template  struct Num {
    const static int value = N;
};
template  struct Sum {
    static const int r = A::value + B::value;
    typedef Num result;
};
int main() {
    std::cout << Reduce<
        Lst<Num<2>, Lst<Num<4>, Lst<Num<6>, Lst< Num<8> > > > >,
        Sum >::result::value << "n";
    return 0;
}

Nothing too fancy, plain old recursion with a sum. Yet it's quite verbose, can we make this a little bit more terse and, hopefully, more clear? Yes, we can. Take a look at that Lst, Lst<...> It sucks. And it's the perfect place to use variadic templates, we just need to construct a structure getting a list of ints, like this:

template <
    // The operation we wish to apply
    template class Op,
    // Current element to process
    class H,
    // All the rest
    class... T>
struct Reduce_V
{
    // TODO
}

That one should look familiar from last time article. Now, to implement a reduce operation we need to operate the current element with the result of reducing the tail, so we have to do something like this:

// Remember how T... means to expand T for the next instance
    typedef typename Reduce_V::result Tail_Result

There's something missing. Can you see what? The ending condition, of course. Let's add it and we'll get something like this:

template <
        // The operation we wish to apply
        template class Op,
        // All the rest
        class... T>
struct Reduce_V
{
};
template <
        // The operation we wish to apply
        template class Op,
        // All the rest
        class H>
struct Reduce_V
{
    typedef H result;
};
template <
        // The operation we wish to apply
        template class Op,
        // Current element to process
        class H,
        // All the rest
        class... T>
struct Reduce_V
{
        // Remember how T… means to expand T for the next instance
   typedef typename Reduce_V::result Tail_Result;
   // Reduce current value with the next in line
   typedef typename Op::result result;
};

And using it is very simple too:

std::cout << Reduce_V< Sum, Num<1>, Num<2>, Num<3>, Num<4>>::result::value << "n";

Next time we'll see another example for variadic templates and a new C++0x feature.

Cool C++0X features V: Templates and angle brackets, a short interlude

Published 2011-05-10

In the heart of C++ template metaprogramming and code obfuscation, lies the (ab)use of angle brackets. This seemingly innocent token can turn the most clean looking code into the mess that template-detractors like so much to complain about.

C++0x doesn't do much to clean up this mess, it's probably impossible, but it does offer a subtle feature to improve the legibility of C++ template code, a nifty little feature we have (inadvertently) used.

Up to C++0x, having two angle brackets together (>>) was parsed as the shift operator (like the one cout uses), meaning that if you had nested templates a lot of compiler errors ensued. C++0x corrects this, meaning that code which in C++ would be like this:

Reduce<Sum, Lst<Num<2>, Lst<Num<4>, Lst<Num<6>, Lst< Num<8> > > > > >

Can now be written like this:

Reduce<Sum, Lst<Num<2>, Lst<Num<4>, Lst<Num<6>, Lst< Num<8>>>>>>

Aaand, back to the normal schedule...

Cool C++0X features VIII: Variadic wrapper and type inference with decltype

Published 2011-05-31

The wrapper function we built last time looks something like this now:

#include 
void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
template 
void wrap(Args... a) {
    std::cout << PRETTY_FUNCTION << "n";
    do_something(a...);
}
int main() {
    wrap();
    wrap("nice");
    return 0;
}

But, as we saw last time, this approach has the problem of requiring the return type of do_something to be known before hand. What can we do to remove this dependency? In C++, not much. You can't really declare a type based on the return type of another function. You do have the option of using lots of metaprogramming wizardy, but this is both error prone and ugly (see Stroustroup's C++0x FAQ).

C++0x lets you do some magic with type inference using decltype; decltype(expr) will yield the type of that expression. It works quite similarly as sizeof does; decltype is resolved at compile time and the expression with which it's being called is not evaluated (more on this later).

How would this work on our example?

#include 
void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
int do_something(int) { std::cout << PRETTY_FUNCTION << "n"; return 123; }
template 
auto wrap(Args... a) -> decltype( do_something(a...) ) {
    std::cout << PRETTY_FUNCTION << "n";
    return do_something(a...);
}
int main() {
    wrap();
    wrap("nice");
    int x = wrap(42);
    std::cout << x << "n";
    return 0;
}

Try it (remember to add -std=c++0x) it works great! The syntax is not so terribly difficult to grasp as it was with variadic templates. The auto keywords says "hey, compiler, the return type for this method will be defined later", and then the -> actually declares the return type. This means that the auto-gt idiom isn't part of typedecl but a helper, which in turns means that even if not useful, this is valid C++0x code:

auto wrap() -> void {
}

This means that we have three interesting components to analyze in this scenario: * -> (delayed declaration) * auto * decltype

We'll go over each one the next time.

Closing remark: At first I choose the following example to introduce delayed return types and decltype (warning, untested code ahead):

#include 
struct Foo {
    void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
    void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
    int do_something(int) { std::cout << PRETTY_FUNCTION << "n"; return 123; }
};
// Untested code ahead
// This makes g++ coredump (v 4.4.5)
template 
struct Wrap : public T {
    template 
    auto wrap(Args... a) -> decltype( T::do_something(a...) ) {
        std::cout << PRETTY_FUNCTION << "n";
        return T::do_something(a...);
    }
};
int main() {
    Wrap w;
    w.wrap();
    w.wrap("nice");
    std::cout << w.wrap(42) << "n";
    return 0;
}

Though this looks MUCH better (and useful), at the time of writing this article mixing variadic templates with decltypes in a template class makes g++ segfault. It should be valid C++, but I can't assure it's correct code since I've never tried it.

Cool C++0X features VIII: Variadic wrapper and type inference with decltype

Published 2011-05-31

The wrapper function we built last time looks something like this now:

#include 
void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
template 
void wrap(Args... a) {
    std::cout << PRETTY_FUNCTION << "n";
    do_something(a...);
}
int main() {
    wrap();
    wrap("nice");
    return 0;
}

But, as we saw last time, this approach has the problem of requiring the return type of do_something to be known before hand. What can we do to remove this dependency? In C++, not much. You can't really declare a type based on the return type of another function. You do have the option of using lots of metaprogramming wizardy, but this is both error prone and ugly (see Stroustroup's C++0x FAQ).

C++0x lets you do some magic with type inference using decltype; decltype(expr) will yield the type of that expression. It works quite similarly as sizeof does; decltype is resolved at compile time and the expression with which it's being called is not evaluated (more on this later).

How would this work on our example?

#include 
void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
int do_something(int) { std::cout << PRETTY_FUNCTION << "n"; return 123; }
template 
auto wrap(Args... a) -> decltype( do_something(a...) ) {
    std::cout << PRETTY_FUNCTION << "n";
    return do_something(a...);
}
int main() {
    wrap();
    wrap("nice");
    int x = wrap(42);
    std::cout << x << "n";
    return 0;
}

Try it (remember to add -std=c++0x) it works great! The syntax is not so terribly difficult to grasp as it was with variadic templates. The auto keywords says "hey, compiler, the return type for this method will be defined later", and then the -> actually declares the return type. This means that the auto-gt idiom isn't part of typedecl but a helper, which in turns means that even if not useful, this is valid C++0x code:

auto wrap() -> void {
}

This means that we have three interesting components to analyze in this scenario: * -> (delayed declaration) * auto * decltype

We'll go over each one the next time.

Closing remark: At first I choose the following example to introduce delayed return types and decltype (warning, untested code ahead):

#include 
struct Foo {
    void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
    void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
    int do_something(int) { std::cout << PRETTY_FUNCTION << "n"; return 123; }
};
// Untested code ahead
// This makes g++ coredump (v 4.4.5)
template 
struct Wrap : public T {
    template 
    auto wrap(Args... a) -> decltype( T::do_something(a...) ) {
        std::cout << PRETTY_FUNCTION << "n";
        return T::do_something(a...);
    }
};
int main() {
    Wrap w;
    w.wrap();
    w.wrap("nice");
    std::cout << w.wrap(42) << "n";
    return 0;
}

Though this looks MUCH better (and useful), at the time of writing this article mixing variadic templates with decltypes in a template class makes g++ segfault. It should be valid C++, but I can't assure it's correct code since I've never tried it.

Cool C++0X features VIII: Variadic wrapper and type inference with decltype

Published 2011-05-31

The wrapper function we built last time looks something like this now:

#include 
void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
template 
void wrap(Args... a) {
    std::cout << PRETTY_FUNCTION << "n";
    do_something(a...);
}
int main() {
    wrap();
    wrap("nice");
    return 0;
}

But, as we saw last time, this approach has the problem of requiring the return type of do_something to be known before hand. What can we do to remove this dependency? In C++, not much. You can't really declare a type based on the return type of another function. You do have the option of using lots of metaprogramming wizardy, but this is both error prone and ugly (see Stroustroup's C++0x FAQ).

C++0x lets you do some magic with type inference using decltype; decltype(expr) will yield the type of that expression. It works quite similarly as sizeof does; decltype is resolved at compile time and the expression with which it's being called is not evaluated (more on this later).

How would this work on our example?

#include 
void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
int do_something(int) { std::cout << PRETTY_FUNCTION << "n"; return 123; }
template 
auto wrap(Args... a) -> decltype( do_something(a...) ) {
    std::cout << PRETTY_FUNCTION << "n";
    return do_something(a...);
}
int main() {
    wrap();
    wrap("nice");
    int x = wrap(42);
    std::cout << x << "n";
    return 0;
}

Try it (remember to add -std=c++0x) it works great! The syntax is not so terribly difficult to grasp as it was with variadic templates. The auto keywords says "hey, compiler, the return type for this method will be defined later", and then the -> actually declares the return type. This means that the auto-gt idiom isn't part of typedecl but a helper, which in turns means that even if not useful, this is valid C++0x code:

auto wrap() -> void {
}

This means that we have three interesting components to analyze in this scenario: * -> (delayed declaration) * auto * decltype

We'll go over each one the next time.

Closing remark: At first I choose the following example to introduce delayed return types and decltype (warning, untested code ahead):

#include 
struct Foo {
    void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
    void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
    int do_something(int) { std::cout << PRETTY_FUNCTION << "n"; return 123; }
};
// Untested code ahead
// This makes g++ coredump (v 4.4.5)
template 
struct Wrap : public T {
    template 
    auto wrap(Args... a) -> decltype( T::do_something(a...) ) {
        std::cout << PRETTY_FUNCTION << "n";
        return T::do_something(a...);
    }
};
int main() {
    Wrap w;
    w.wrap();
    w.wrap("nice");
    std::cout << w.wrap(42) << "n";
    return 0;
}

Though this looks MUCH better (and useful), at the time of writing this article mixing variadic templates with decltypes in a template class makes g++ segfault. It should be valid C++, but I can't assure it's correct code since I've never tried it.

Cool C++0X features IX: delayed type declaration

Published 2011-06-07

In the last two entries we worked on a wrapper object which allows us to decorate a method before or after calling (hello aspects!), or at least that's what it should do when g++ fully implements decltypes and variadic templates. Our wrapper function looks something like this (check out the previous entry for the wrapper object):

#include 
void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
int do_something(int) { std::cout << PRETTY_FUNCTION << "n"; return 123; }
template 
auto wrap(Args... a) -> decltype( do_something(a...) ) {
    std::cout << PRETTY_FUNCTION << "n";
    return do_something(a...);
}
int main() {
    wrap();
    wrap("nice");
    int x = wrap(42);
    std::cout << x << "n";
    return 0;
}

After the example, we were left with three new syntax changes to analyze: * -> (delayed declaration) * decltype * auto

Let's study the -> operator this time: -> (delayed declaration) This is the easiest one. When a method is declared auto (I've left this one for the end because auto is used for other things too) it means its return type will be defined somewhere else. Note that in this regard the final implementation differs from Stroustroup's FAQ.

The -> operator in a method's definition says "Here's the return type". I'll paste the same simple example we had last time, the following two snippets of code are equivalent:

void foo() {}

Is the same as:

auto foo() -> void {}

Cool C++0X features X: type inference with decltype

Published 2011-06-10

After creating a wrapper object on the last entries, we were left with three syntax changes two analyze:

We already saw the first, and we'll be talking about the other two this time. This was the original wrapper function which led us here:

template 
auto wrap(Args... a) -> decltype( do_something(a...) ) {
    std::cout << PRETTY_FUNCTION << "n";
    return do_something(a...);
}

Back on topic: decltype This operator (yes, decltype is an operator) is a cousin of sizeof which will yield the type of an expression. Why do I say it's a cousin of sizeof? Because it's been in the compilers for a long time, only in disguise. This is because you can't get the size of an expression without knowing it's type, so even though it's implementation has existed for a long time only now it's available to the programmer.

One of it's interesting features is that the expression with which you call decltype won't be evaluated, so you can safely use a function call within a decltype, like this:

auto foo(int x) -> decltype( bar(x) ) {
    return bar(x);
}

Doing this with, say, a macro, would get bar(x) evaluated twice, yet with decltype it will be evaluated only once. Any valid C++ expression can go within a decltype operator, so for example this is valid too:

template 
auto multiply(A x, B y) -> decltype( xy )
{
    return xy;
}

What's the type of A and B? What's the type of A*B? We don't care, the compiler will take care of that for us. Let's look again at that example, more closely:

-> (delayed declaration) and decltype Why bother creating a delayed type declaration at all and not just use the decltype in place of the auto? That's because of a scope problem, see this:

// Declare a template function receiving two types as param
template 
// If we are declaring a multiplication operation, what's the return type of AB?
// We can't multiply classes, and we don't know any instances of them
auto multiply(A x, B y)
// Luckily, the method signature now defined both parameters, meaning
// we don't need to expressly know the type of AB, we just evaluate
// xy and use whatever type that yields
    -> decltype( xy )
{
    return x*y;
}

decltype As you see, decltype can be a very powerful tool if the return type of a function is not known for the programmer when writing the code, but you can use it to declare any type, anywhere, if you are too lazy to type. If you, for example, are very bad at math and don't remember that the integers group is closed for multiplication, you could write this:

    int x = 2;
    int y = 3;
    decltype(xy) z = xy;

Yes, you can use it as VB's dim! (kidding, just kidding, please don't hit me). Even though this works and it's perfectly legal, auto is a better option for this. We'll see that on the next entry.

Cool C++0X features XI: decltype and disappearing constness

Published 2011-09-27

After a long, long hiatus, the C++0x series are back. You may want to check where we left by reading the last posts of this series.

In the last few entries we saw how to use decltype for type inference. Object types is a problem that seems easy but gets complicated very quickly, for example when you start dealing with constness. Constness is difficult in many ways but this time I want to review how constness works with type inference. This topic is not C++0x specific as it's present for template type deduction too, but decltype adds a new level of complexity to it.

Let's start with an example. Would this compile?

struct Foo {
    int bar;
};
void f(const Foo foo)
{
    foo.bar = 42;
}

Clearly not, having a const Foo means you can't touch foo.bar. How about this?

struct Foo {
    int bar;
};
void f(const Foo foo)
{
    int& x = foo.bar;
}

That won't compile either, you can't initialize an int reference from a const int, yet we can do this:

void f(const Foo foo)
{
    const int& x = foo.bar;
}

If we know that works it must mean that s.result's type is const int. Right? Depends.

Just as the name implies decltype yields the declared type of a variable, and what's the declared type for Foo.bar?

struct Foo {
    int bar;
};
void f(const Foo foo)
{
    // This won't compile
    int& x = foo.bar;
    // This will
    decltype(foo.bar) x = 42;
}

That's an interesting difference, but it makes sense once you are used to it. To make things more interesting, what happens if you start adding parenthesis (almost) randomly? Try to deduce the type of x:

void f(const Foo foo)
{
    decltype((foo.bar)) x
}

If decltype(x) is the type of x then decltype((foo.bar)) is the type of (foo.bar). Between foo.bar and (foo.bar) there's a very important difference; the first refers to a variable whilst the last refers to an expression. Even though foo.bar was declared as int, the expression (foo.bar) will yield a const int&, since that's the type (though implicit and not declared, since the expression is not declared).

This is how we would complete the example then:

void f(const Foo foo)
{
    // These two statements are equivalent
    decltype((foo.bar)) x = 42;
    const int& y = 42;
    // It's very easy to confirm that the typeof x is now const int&
    // This won't compile:
    x = 24;
}

As I said, disappearing constness is not a C++0x specific problem as it may occur on template type deduction, but that's besides the point of this post. Next time we'll continue working with type deduction, but with the new auto feature this time.

Cool C++0X features XII: type inference with auto

Published 2011-10-04

In the last four entries we worked on a simple example, like the one I'm pasting below, of type inference with decltype, which led us to learn about delayed type declaration and decltypes with auto. This time I want to focus just on the auto keyword instead.

template 
auto wrap(Args... a) -> decltype( do_something(a...) ) {
    std::cout << PRETTY_FUNCTION << "n";
    return do_something(a...);
}

We saw last time how decltype can be used in a contrived way to create a local variable without specifying its type, only how to deduce the type for this variable. Luckily, that verbose method of type declaration can be summed up in the following way:

    int x = 2;
    int y = 3;
    decltype(xy) z = xy;

Should be written as:

    int x = 2;
    int y = 3;
    auto z = x*y;

That's right, when you are declaring local variables it's easier and cleaner to just use auto. This feature isn't even "in the wild" yet, so you can't really predict what will people do with it, but it seems to me that limiting its use to local variables with a very short lived scope is the best strategy. We are yet to see what monstrosities the abuse of this feature will produce, and I'm sure there will be many. Regardless of their potential to drive insane any maintainers, its best use probably comes in loops.

In any C++ application, you'll find code like this:

for (FooContainer::const_iterator i = foobar.begin(); i != foobar.end(); ++i)

This ugly code can be eliminated with something much more elegant:

for (auto i = foobar.begin(); i != foobar.end(); ++i)

Looks nicer indeed, but we can improve it much further with other tools. We'll see how the next time. For the time being, let's see for what auto is not to be used.

When using auto, keep in mind it was designed to simplify the declaration of a variable with a complex or difficult to reason type, not as a replacement for other language features like templates. This is a common mistake:

Wrong:

void f(auto x) {
    cout << x;
}

Less wrong:

template 
void f(T x) {
    cout << x;
}

It makes no sense to use auto in the place of a template, since a template means that the type will be completed later whereas auto means it should be deduced from an initializer.

Cool C++0X features XIII: auto and ranged for, cleaner loops FTW

Published 2012-11-29

Long time without updating this series. Last time we saw how the ugly

for (FooContainer::const_iterator i = foobar.begin(); i != foobar.end(); ++i)

could be transformed into the much cleaner

for (auto i = foobar.begin(); i != foobar.end(); ++i)

Yet we are not done, we can clean that a lot more using for range statements.

Ranged for is basically syntactic sugar (no flamewar intended) for shorter for statements. It's nothing new and it's been part of many languages for many years already, so there will be no lores about the greatness of C++ innovations (flamewar intended), but it still is a nice improvement to have, considering how tedious can be to write nested loops. This certainly looks much cleaner:

for (auto x : foobar)

This last for-statement, even though it looks good enough to print and hang in a wall, raises a lot of questions. What's the type of x? What if I want to change its value? Let's try to answer that.

The type of the iterator will be the same as the type of the vector, so in this case x would be an int:

std::vector foobar;
for (auto x : foobar) {
    std::cout << (x+2);
}

And now, what happens if you want to alter the contents of a list and not only display them? That's easy too, just declare x as an auto reference:

std::vector foobar;
for (auto& x : foobar) {
    std::cout << (x+2);
}

This looks really nice but it won't really do anything, for two different reasons:

There are many ways to initialize that list, but we'll see how C++0X let's you do it in a new way the next time.

Cool C++0X features XIV: Initializer lists

Published 2011-10-11

We talked last time about ranged fors and how they can simplify our life in C++0x. Now we are going to take a trip back to old C land. Remember when you could initialize your arrays like this:

int v[] = {1, 2, 3, 4};

C++0X brought a lot of changes to the world, and suddenly instead of int[] you were supposed to use vector, and with it your initializer didn't work anymore. Though luck. Try to compile this:

#include 
int main() {
    std::vector v = {1,2,3,4};
    return 0;
}

If you did compile it with g++, you may have noticed an interesting error message:

error: in C++98 'v' must be initialized by constructor, not by '{...}'
warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x

That's interesting. Try to compile it with g++ again, but using C++0x instead of plain C++. Magic, now it works!

Initializers lists bring the best of C to C++ world (?) by letting you use initialize any object with an initializer. And I mean *any* object, not just vectors. For example, say you have a map (a map and a bunch of other stuff):

int main() {
    map> v = {
            { "a", {1,2,3} },
            { "b", {4,5,6} },
            { "c", {7,8,9} }
        };
    cout << v["b"][1] << "n";
    return 0;
}

Yes, that works! Maps, vectors, pairs, and even your own custom objects, but we'll see that next time.

Cool C++0X features XV: Initializer lists for custom (non-std) objects

Published 2011-10-18

Last time we saw how you can use C style array-initialization for C++ objects, like this:

    std::vector v = {1,2,3,4};

We also saw this works for may types of objects, like maps and pairs. How about custom developed objects? Yes, that's right, you can have initilizer lists for your own objects too, and it's quite easy. C++0x offers initializer_lists which you can use on your constructors (or any other methods, for that mater) to have C-style initialization. Let's see an example. We already know how to sum a list of numbers using template lists and variadic templates, so let's try adding an initializer consisting of numbers:

Let's start by creating a class which can accept an initializer list:

#include 
using namespace std;
struct Add_List {
    Add_List(initializer_list lst) {
    }
};
int main() {
    Add_List x = {1, 2, 3};
    return 0;
}

That's interesting, as you can see an initializer list is actualy a template class, meaning that nested initializers can easily be defined too. Now, we have the interface, how can we access each element of the list? Let's do the same thing I did when I found out about initilizers, let's search for the header file.

  template
    class initializer_list
    {
    public:
      typedef _E        value_type;
      typedef const _E&     reference;
      typedef const _E&     const_reference;
      typedef size_t        size_type;
      typedef const _E     iterator;
      typedef const _E     const_iterator;
    private:
      iterator          _M_array;
      size_type         _M_len;
      // The compiler can call a private constructor.
      initializer_list(const_iterator __a, size_type __l)
      : _M_array(__a), _M_len(__l) { }
    public:
      initializer_list() : _M_array(NULL), _M_len(0) { }
      // Number of elements.
      size_type
      size() const { return _M_len; }
      // First element.
      const_iterator
      begin() const { return _M_array; }
      // One past the last element.
      const_iterator
      end() const { return begin() + size(); }
  };

Looks surprisingly easy (note that this is for G++ 4.something only). And it is, most of the magic happens in the compiler, so the userland code is quite straight forward. According to that header file, we could build something like this:

#include 
#include 
using namespace std;
struct Add_List {
    Add_List(initializer_list lst) {
        int sum = 0;
        for (auto i = lst.begin(); i != lst.end(); ++i)
            sum += *i;
        cout << sum << "n";
    }
};
int main() {
    Add_List x = {1, 2, 3};
    return 0;
}

As you can see, the initializer lists can be used in any place an iterable container is required, as long as it's const. There's not much more magic to it, but we can use some more C++0x devices to make our list-adding device much more cool, for example to support different actions and not only addition. Next time, though.

PS: An important lesson from this article: don't be afraid to look into the system headers, they won't bite. You should never ever change them, but taking a peek can only improve your C++ knowledge.

Cool C++0X features XVI: Lambdas

Published 2013-01-08

Last time we created a device to sum an initializer list of ints, something like this:

void Add(initializer_list lst) {
    int sum = 0;
    for (auto i = lst.begin(); i != lst.end(); ++i)
        sum += *i;
    cout << sum << "n";
}

And then we said this can be improved using some new C++0x wizardry to support actions other than adding. How would we do that? Easy, we need to decouple the iteration of the list from the operation logic. We can do something like this:


// Note how we don't care about the type of OP, just that
// it can be called (i.e. has an operator ())
template 
void do_something(OP op, int init, initializer_list lst) {
    int sum = init;
    for (auto i = lst.begin(); i != lst.end(); ++i)
    {
        int x = *i;
        sum = op(sum, x);
    }
    cout << sum << "n";
}
struct Sum {
    int operator() (int a, int b)
    {
        return a + b;
    }
};
int main() {
    do_something(Sum(), 0, {1, 2, 3, 4});
    return 0;
}

We had to do some changes other than passing the operation-object into the do_something method; since the start value (zero) was hardcoded we had to remove it to really decouple the action from the iteration.

Other than creating a function object (which is the correct name for the object wrapping our operation) we don't see any strange changes, there's no C++0x there, but C++0x gives us a little tool which gives you the power of creating much simpler and nicer code, or to make the next maintainers' life a living hell. That's a discussion for other time though, now let's take a sneak preview a lambdas, the evolution of function objects:

int main() {
    auto f = [] (int a, int b){ return a+b; } ;
    do_something(f, 0, {1, 2, 3, 4});
    return 0;
}

Note that we didn't change anything on the method iterating the list, we just changed main! There's a lot to talk about lambdas, so this is only an intro to the subject. Next time we'll discuss the subtleties of the new syntax.

Cool C++0X features XVII: Lambdas syntax

Published 2013-01-10

After creating a device to sum an initializer list as an example of this new feature last time, we created a generic function to receive a function object, which worked just very similarly to Smalltalk's inject. After creating the usual function object, overloading the () operator, we saw a much cooler way of doing that using lambdas, like this:

int main() {
    auto f = [] (int a, int b){ return a+b; } ;
    do_something(f, 0, {1, 2, 3, 4});
    return 0;
}

Pretty cool. Pretty weird too. Let's analyze how to declare a lambda before we continue discussing about the usage of this new feature.

auto f

Auto f. Lambdas have a type, and you can explicitly declare it. The type might be quite complicated though, and it doesn't really add any information that makes reading the code any easier, so we are better off using C++0x's new feature, auto, which will infer the type for us. Saves a lot of typing, trust me.

auto f = [] (int a, int b)

Brackets, and then the parameters specification. Looks weird but the brackets are there just to tell the compiler "hey, an anonymous method comes here" (actually the brackets could be omitted in this case but we'll need them later on). After that, it's just a normal method declaration. Useless trivia: before C++0x you could have anonymous objects but not anonymous methods. Can you think where would you have an anonymous object? I think I even wrote an article about it on this blog, but I'm too lazy to search for it.

auto f = [] (int a, int b) { return a+b; }

After the lambda's signature, which is the same as the signature of a common method, you have the body of the method. It can be as short or as long as you want, it's just a method's body (though for the sanity of the maintainer you'd better keep it short).

Watch out though, that's not the end of the declaration, we're missing a crucial piece on this lambda:

auto f = [] (int a, int b) { return a+b; };

I'd use the blink tag, but I think it has been deprecated. Notice that last semicolon; when you declare the lambda's body you finish with a semicolon inside, just as you would inside a normal method, but that's not the end of the expression, for the lambda declared outside the body of that method still needs another semicolon to appraise the compiler god.

And now, we know almost everything we need to know about lambda's syntax. Notice how the return type of the method is automagically deduced. That's useful, but there's something the compiler can't deduce by itself about the return type. If you are trying to return a reference to something, you need to make this explicit, the compiler has no way of detecting if you need a copy return or a reference return (until the next draft of C++, which I heard incorporates mind reading capabilities into the compiler. You may have to wait a couple of years though). This is easy to specify, though:

auto f = [&] (int a, int b) { return a+b; };

Just add an ampersand between the brackets and the lambda will return a reference instead of a copy of whatever object you're trying to return. How about receiving a reference instead of returning one? That's easy, remember the signature is the same as any other method:

auto f = [] (int& a, int& b) { return a+b; };

That's it, now we know how to use basic lambdas. You should keep in mind, though, this mythical beast has a lot more to it than just its syntax. We'll discuss about some of it's darkest secrets, how to use it, when to use it, how does it work. That discussion is for next time, though.