Question

In C++11 you can create a "type alias" by doing something like

template <typename T>
using stringpair = std::pair<std::string, T>;

But this is a deviation from what you'd expect a template typedef would look like:

template <typename T>
typedef std::pair<std::string, T> stringpair;

So this raises the question - why did they need to come up with a new syntax? what was it that did not work with the old typedef syntax?

I realize the last bit doesn't compile but why can't it be made to compile?

Was it helpful?

Solution 2

From the WG21 proposal N1489 Template aliases (by Stroustrup and Dos Reis):

It has been suggested to (re)use the keyword typedef as done in the paper [4] to introduce template aliases:

 template<class T> 
 typedef std::vector<T, MyAllocator<T> > Vec;

That notation has the advantage of using a keyword already known to introduce a type alias. However, it also displays several disavantages among which the confusion of using a keyword known to introduce an alias for a type-name in a context where the alias does not designate a type, but a template; Vec is not an alias for a type, and should not be taken for a typedef-name. The name Vec is a name for the family std::vector<o, MyAllocator<o> > where the bullet is a placeholder for a type-name. Consequently we do not propose the typedef syntax.

On the other hand the sentence

template<class T> 
using Vec = std::vector<T, MyAllocator<T> >;

can be read/interpreted as: from now on, I'll be using Vec<T> as a synonym for std::vector<T, MyAllocator<T> >. With that reading, the new syntax for aliasing seems reasonably logical.

The paper [4] referred to in the above quote was a prior proposal WG21 N1406 Proposed Addition to C++: Typedef Templates (by Herb Sutter). It uses both a different syntax (typedef vs using) as well as a different nomenclature (typedef templates vs template aliases). Herb's proposed syntax didn't make it, but the nomenclature can sometimes be found in informal discussions.

OTHER TIPS

I'll just refer to stroustrup himself:

http://www.stroustrup.com/C++11FAQ.html#template-alias

The keyword using is used to get a linear notation "name followed by what it refers to." We tried with the conventional and convoluted typedef solution, but never managed to get a complete and coherent solution until we settled on a less obscure syntax.

(tl;dr: using supports templates, whereas typedef does not.)


As it sounds like you know already, the difference between the two examples without templates is nothing:

[C++11: 7.1.3/2]: A typedef-name can also be introduced by an alias-declaration. The identifier following the using keyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. It has the same semantics as if it were introduced by the typedef specifier. In particular, it does not define a new type and it shall not appear in the type-id.

However, template typedefs do not exist!

[C++11: 14.5.7/1]: A template-declaration in which the declaration is an alias-declaration (Clause 7) declares the identifier to be a alias template. An alias template is a name for a family of types. The name of the alias template is a template-name.

Why didn't they simply re-use typedef syntax? Well, I think typedef is simply the "old" style and, given the use of using in other contexts, it was decided that new functionality should take the using form for consistency.

One more reason for the new syntax - typedefs for functions, arrays and similar constructs become a bit more comprehensible.

Reference to array before / after:

typedef int(&my_type)[3];
using my_type = int(&)[3];

Array of function pointers before / after:

typedef void(*my_type[3])();
using my_type = void(*[3])();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top