What was the issue solved by the new “using” syntax for template typedefs?

ⅰ亾dé卋堺 提交于 2019-12-04 23:03:26

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.

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])();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!