Template Metaranting

Here’s another post in the series, this time it’s C++ vs. the D programming language.

Let’s talk about templates.
If you’ve ever tried templates in C++ you surely as hell recall the pages and PAGES of compiler errors and seemingly random placement of typename keyword.
Trust me, there are EVEN WORSE problems with templates in C++… Consider the following:

 1:  struct Foo {
 2:    template<int N>
 3:    void bar() {}
 4:  
 5:    template<int N>
 6:    struct Bar {};
 7:  };
 8:  
 9:  template<typename T>
10:  void f() {
11:    T foo;
12:    foo.template bar<0>();
13:    typename T::template Bar<0> b;
14:  }
15:  
16:  int main() {
17:    f<Foo>();
18:  }
19:  

This little snippet is pretty simple, but… OH GOD! Lines 12 and 13. What the hell?

Line 12 shows the so-called object.template function<arg>() syntax and it is probably the least known C++ syntax out there.
The reason it exists is simple – in this particular corner case the compiler simply… can’t… parse… this code.
When parsing f() functions definition it can’t possibly know that T foo has a templated member bar and confuses the template opening bracket with the less-than operator, so we end up with an unresolved overloaded function type error. That’s harsh.

Line 13 contains a similar corner case where we need to use all kinds of messed up syntax just to declare a variable.
The typename tells the compiler that we want a type because you know, it won’t figure it out on its own. Next, we access with a :: the templated member type Bar instantiated with a 0. The template is there for the same reason it’s found on line 12.

Here’s the semantically equivalent code in the D programming language:

 1:  struct Foo {
 2:    void bar(int N)() {}
 3:  
 4:    struct Bar(int N) {}
 5:  }
 6:  
 7:  void f(T)() {
 8:    T foo;
 9:    foo.bar!0();
10:    T.Bar!0 b;
11:  }
12:  
13:  void main() {
14:    f!Foo();
15:  }
16:  

The analogous lines (9 & 10) will always mean the same and don’t require disambiguation with any keywords.

C++’ template problem may not seem that serious, but imagine more complicated templates and, oh snap, debugging their code and all the weird stuff that happens when you forget a random template keyword somewhere.
And I didn’t even start ranting about…

// ...C++11. *
template <size_t k, class T, class... Ts>
typename enable_if<k != 0, typename tuple_element<k, tuple<T, Ts...>>::type&>::type // WAT
get(tuple<T, Ts...>& t) {
  tuple<Ts...> & super = t;
  return get<k - 1>(super);
}

To sum it up, D’s template syntax is simpler, corner cases don’t exist and declarations are cleaner. This is a yet another reason I like D so much.


* The snippet comes from an awesome presentation given by Andrei Alexandrescu on the Going Native 2012 conference a while ago. I didn’t get into any details because it’s a topic for another rant. Stay tuned.

About these ads

4 Responses to Template Metaranting

    • A nice example is the `std.functional.memoize’ function comming from D’s strandard library Phobos:

      ReturnType!fun memoize(alias fun)(ParameterTypeTuple!fun args) {
          // Implementation...
      }
      

      This simplified version takes a function as its template parameter and has both templated arguments and templated return type.
      The `ParameterTypeTuple!fun’ extracts a `TypeTuple’ of `fun’s parameter types and the `ReturnType!fun’ is rather selfexplanatory.

      As you can see first parentheses in a function declaration contain template parameters that can be used both in the runtime parameters and the return type and there is no need for a `typename’ keyword.

      Hopefully this will give you a general idea, because I really, really don’t want to decipher any C++11 code… ;)

  1. Pingback: Templated Monads? Monadic Templates? | I do robots

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s