Category Archives: Names

Dreaming of Names

Lets take a look at a simple struct:

Ok, that is simple. A struct with a member

  • type int
  • default value 42
  • called id

Lets suppose we want to make this compile-time configurable. Well, you think, this is still simple, and you probably have something like this in mind:

Now this template has a member of

  • configurable type
  • configurable default value

But the member is still called id and there is nothing you can do to make this configurable (unless you are into preprocessor macros)

This is driving me nuts because I really need configurable names for sqlpp11 and it is such an effort to this kind of stuff today (using variadic inheritance to create tables an result rows with appropriately typed and named data members).

The feedback I received for a workshop at CppCon 2014 and a talk at the Munich C++ Meetup tells me that others have similar needs.

Dreaming

I would really like to be able to write a template like this:

And then use it in the following way for instance:

Just lean back and think about it for a moment. Being able to have names as template parameters? Why would that be useful?

Here are some ideas:

Named Tuples

Tuples are great for generic programming. But for library interfaces? Not always. Sometimes you’re just too lazy to write a struct with 5 elements and to define comparison operators. And you leave it up to the user of the library to use std::tie or std::get to access the tuple members.

How about you could define tuples that have directly accessible data members with reasonable names?

Assuming we can use names as template parameters, lets define a small helper:

Then we could define a named tuple just like that:

And then use it like this, for example:

So now we have a tuple that has appropriately typed and named members. In non-generic contexts, this is so much nicer to use.

Admittedly, I omitted a few details. Like constructors or the comparison operators, for instance. As an example, here is what a less operator for named tuples could look like.

(By the way, this is pretty close to the first target use case of the SG7 call for papers: Generating equality operators)

How about std::get or std::tie or whatnot? I leave that to you 🙂

Replacing CRTP

CRTP (Curiously recurring template pattern) always feels weird to me. I use it, but it feels weird.

Here is an example that works today:

Admittedly, this is even worse than most introductory examples, since the derived struct is parametrized with the base template instead of a base class. But it is still much simpler than what I use in sqlpp11, where I have a variadic form of this.

Anyway, using CRTP, you can define certain bits of functionality once and then add them to one or more derived classes.

Cool. This actually works.

Wait, what? Cool? Seriously? It gives me the creeps!

  • Public inheritance without a real “IsA” relationship, and Sean Parent said that inheritance is the base class of evil, didn’t he?
  • The typical static cast to the derived class is just gross.
  • The order of instantiation requires the base class often to use TMP tricks to access information from the derived class.
  • And try to do that with a variadic number of CRTP bases, it works, but it is ugly.

Could we do better?

If we could reason about names, as described above, yes, we could! Here’s the idea:

What happens here? The mixin struct defines a name (check).  It is then instantiated in MyClass using this name. MyClass now has a callable member called check.

This approach is so much simpler:

  • There is no inheritance involved
  • There is no need to statically cast oneself to a derived thing
  • Even having a variadic number of mixins does not make the whole thing harder to grok.

Admittedly, there is also a drawback: Each mixin requires to store the pointer to the object it is used in. This approach is therefore certainly not suited for all situations.

The Struct-of-Arrays vector

Another (incomplete) usecase of names would be type transformations based on reflection. Say we had a struct

We want to create a struct of arrays from it (see SG7 Call for papers) and some reflection capability identifies the name of the data members, then we could simply use the following StructOfArrays template:

Like this:

And of course

Libraries like sqlpp11 would greatly benefit from being able to reason about names. Tables, columns and result fields all have names. And these names are being used by the users of the library (not as strings, but as real C++ names). Tables and SQL statements are represented by variadic CRTP constructs. This could be so much simpler if we could use names as described above.

And with reflection, it would be relatively simple to use SQL on C++ data structures or streams. A proof of concept is shown here, but it won’t really fly before we have both reflection and names.

Summary

Pretty much on day one, every programmer learns about the value of using good names. Still, all of C++’s TMP revolves about types and values.

I would really like to be able to reason about names in C++ at compile time as described above.

Let me know, what you think 🙂