Clearly, type aliases and templated type aliases are semantically equivalent to typedefs and an extension of typedefs to support template. How come new syntax with the using
keyword was created for these instead of using typedefs for the first and some syntax extension with the word typedef
.
NOTE: This is not a clone of the "difference between using and typedef" question. I know that using
gives the advantage of defining a family of typedef
s. What I am asking is why did the standard people decide on having this extension use the using
keyword instead of the typedef
keyword. This seems like it just adds confusion in the language.
Here is what Bjarne Stroustrup says about why they introduced using
instead of extending typedef
:
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.
He also claims that he likes this syntax also more for usual typedefs:
In addition to being important in connection with templates, type aliases can also be used as a different (and IMO better) syntax for ordinary type aliases:
using PF = void (*)(double);
He is quite correct here, this seems very clean. In contrast a typedef would be extremely convoluted with the name being somewhere in the middle:
typedef void(*PF)(double);
Here is an explanation (see page 4) from their proposal that is even more in-depth:
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 disadvantages 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 nameVec
is a name for the familystd::vector<*,MyAllocator<*>>
- where the asterisk is a placeholder for a type-name. Consequently, we do not propose the "typedef" syntax.template<class T> using Vec = std::vector<T,MyAllocator<T>>;
can be read/interpreted as: from now on, I'll be using
Vect<T>
as a synonym forstd::vector<T,MyAllocator<T>>
. With that reading, the new syntax for aliasing seems reasonably logical.
So he has basically two points here:
using
template becomes a family of types, not a type, so typedef
is "wrong"using
can be read almost as an english sentence