Daveed has a talk scheduled on January 2nd in New York City. The topic will be “C++ Template Instantiation -- Advanced Concepts.”
The talk is for the C++ and Java SIG (special interest group) of the NYPC users group. If all goes well, we'll start at 6:30pm on the 15th floor of the New Yorker Hotel (34th Street and 8th Avenue).
Part of the talk will be based on Chapter 10 of our new book, but we will probably also spend some significant time on new ideas wrt. exported templates.
In other words, the template arguments (presumably policy classes in the example above) can be provided in any order, provided they are wrapped in a template like Policy3_is that indicates which argument is intended.BreadSlicer<Policy3_is<CustomPolicy> > b1; BreadSlicer<Policy1_is<MyPolicy>, Policy3_is<AnotherPolicy> > b2;
The technique we present to enable this requires a few dozen lines of slightly subtle, somewhat boring code.
However, there are alternatives. Consider the following code:
In this code, every policy or property is a template whose last (and sometimes: only) parameter is meant to be substituted by other parameters. The default for this trailing parameter is a class type Defaults that encapsulates the default properties or policies.struct Defaults { typedef double ElementT; static void move(char*, char*); }; template<typename OtherProps = Defaults> struct Mover: OtherProps { static void move(char*, char*); }; template<typename T, typename OtherProps = Defaults> struct ElementType: OtherProps { typedef T ElementT; }; template<typename Props = Defaults> struct WonderData { // ... }; void my_code() { WonderData<ElementType<long, Mover<> > > data; // ... }
This works and is in some ways considerably simpler than the named template arguments technique presented in our book. This simplicity comes with a different set of compromises, of course.
First, it is syntactically somewhat asymetric, even though semantically it should not be so. Indeed, ElementType<long, Mover<> > looks quite different from Mover<ElementType<long> >, but in fact these two are intended to mean the same thing.
Second, the burden is not put on the writer of the policy or property templates instead of on the writer of the main template. This is not necessarily a disadvantage (especially since that burden is smaller in complexity). However, we prefer to move complexity from client code to the library on the premise that there will be many instances of client code for a single library.
Finally, as written above, the inheritance relationship offers opportunities for unintended clashes between properties or policies, but that can be avoided by adding a typedef member for the actual property or policy (much as is done in our named template arguments technique).
I spent some time revising the design of the C++ Templates pages. It now fits better with the looks of the rest of the site.
I'm working on a Forum section that should allow me to more regularly write some things about templates in general. I already have a note prompted by reader feedback, but I'll wait to add it until everything is in place.