问题
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?
回答1:
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.
回答2:
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.
回答3:
(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.
回答4:
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