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?
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 forstd::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.
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 theusing
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 thetypedef
specifier. In particular, it does not define a new type and it shall not appear in the type-id.
However, template typedef
s 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])();
来源:https://stackoverflow.com/questions/19438407/what-was-the-issue-solved-by-the-new-using-syntax-for-template-typedefs