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

我与影子孤独终老i 提交于 2019-12-06 17:23:33

问题


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 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.




回答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 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.




回答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

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