Why doesn't C ++ 11 have a typedef pattern?
n1406 was a Herb Sutter suggestion for "typedef templates" that mimics the syntax in your question. n1499 , which offers "template aliases," replaces it, which contains the using syntax that is currently present in C ++ 11.
One of the main drawbacks of "typedef patterns" is addressed in both documents. From n1406:
In existing practice, including in the standard library, type names nested inside the helper class are used to work around this problem in many cases. The following is an example of a typical workaround; the main disadvantage is the need to write :: Type when using the name typedefd.
template< typename T > struct SharedPtr { typedef Loki::SmartPtr < T, // note, T still varies RefCounted, // but everything else is fixed NoChecking, false, PointsToOneObject, SingleThreaded, SimplePointer<T> // note, T can be used as here > Type; }; SharedPtr<int>::Type p; // sample usage, "::Type" is uglyWhat you really like is simple:
template< typename T > typedef Loki::SmartPtr < T, // note, T still varies RefCounted, // but everything else is fixed NoChecking, false, PointsToOneObject, SingleThreaded, SimplePointer<T> // note, T can be used as here > SharedPtr; SharedPtr<int> p; // sample usage, "::Type" is ugly[...]
The workaround is ugly, and it would be nice to replace its first-class language support, offering users a natural C ++ syntax pattern.
This "first-class language support" comes in the form of template aliases. Now we can see what n1499 says:
In this article, we will focus on the description of the smoothing mechanism, which allows the two semantics mentioned in N1406, to coexist instead, is considered mutually exclusive. First, consider a toy example:
template <typename T> class MyAlloc {/*...*/}; template <typename T, class A> class MyVector {/*...*/}; template <typename T> struct Vec { typedef MyVector<T, MyAlloc<T> > type; }; Vec<int>::type p; // sample usageThe main problem with this idiom, and the main motivating fact for this proposal, is that the idiom makes the template options appear in an un-deducible context. That is, it will be impossible to call the
foofunction below without explicitly specifying the Arguments pattern.template <typename T> void foo (Vec<T>::type&);In addition, the syntax is somewhat ugly. We would rather avoid the nested :: type call. Wed prefers something like the following:
template <typename T> using Vec = MyVector<T, MyAlloc<T> >; //defined in section 2 below Vec<int> p; // sample usagePlease note that we specifically avoid the term โtypedef patternโ and introduce new syntax involving the pair โusingโ and โ=โ to help avoid confusion: we do not define any types here, we are introducing a synonym (i.e. alias ) for abstraction of the type identifier (i.e. type expression), including template parameters. If the template parameters are used in the displayed contexts in the type expression, then whenever the template alias is used to generate the template identifier, the values โโof the corresponding template parameters can be displayed - more will follow. In any case, you can now write general functions that work on
Vec<T>in the output context, and the syntax is also improved. For example, we could rewritefooas:template <typename T> void foo (Vec<T>&);We emphasize here that one of the main reasons for suggesting template aliases was such that the output of the argument and the call to
foo(p)would succeed.
So you can see that n1499 solves problems in n1406, and also introduces syntax that is much cleaner and easier to read.