39

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

tohava
  • 5,344
  • 1
  • 25
  • 47
  • 3
    @Cyber, it is not. I know that `using` gives the advantage of defining a family of typedefs. 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. – tohava Jul 23 '14 at 16:56
  • 1
    Possibly this has to do with the problems mentioned in N1406 and how N1499 solves them. The solution is reflected in the syntax: template aliases do not *define types*, as a typedef template would suggest, and opposed to the original proposal of typedef templates that allowed specialization (in one version of it). – dyp Jul 23 '14 at 17:12
  • TL;DR because typedef is a horrible unreadable hack and there was an opportunity to supersede it with a cleaner, gentler syntax. – n. m. could be an AI Jul 24 '14 at 12:45
  • dyp typedef doesn't add a type either, traditionally what it is called is a weak type, but that just means there's no new type in the compiler's type table. – phorgan1 Aug 18 '16 at 17:20

2 Answers2

44

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 name Vec is a name for the family std::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 Vec<T> as a synonym for std::vector<T,MyAllocator<T>>. With that reading, the new syntax for aliasing seems reasonably logical.

So he has basically two points here:

  1. A using template becomes a family of types, not a type, so typedef is "wrong"
  2. using can be read almost as an english sentence
αλεχολυτ
  • 4,792
  • 1
  • 35
  • 71
gexicide
  • 38,535
  • 21
  • 92
  • 152
  • 3
    I agree with him on that last point... I'd say `using` should come to replace typedefs. The syntax is much less ambiguous. – ApproachingDarknessFish Jul 23 '14 at 17:13
  • Just for comparison, you should maybe show what a typedef would look like for your `void(*)(double)` example. :) – jalf Jul 23 '14 at 17:14
  • Regarding point 1 the same could have been said of class or struct, not just of typedef. – memeplex Feb 13 '16 at 17:58
  • 1
    Always wondered why they never allowed simply having `typedef void(*)(double) PF;` Would have been (almost) as clear as `using`. Template typedefs - well, yould have worked, one would have got used to it the same as function pointer typedefs... Back to function pointers, actually, I feel alike when defining variables: Why not `int(*)(double) callback;`? I know, philosophy in the end is the same as with `char *a, b, *c;`. A thing I *can* read, but got never friend with and won't ever use myself on code as my personal reading is different... – Aconcagua Jul 18 '16 at 21:10
30

What you suggest was actually proposed back in 2002 in document N1406 by Herb Sutter. It would allow, for example, to write:

template<typename T> typedef X<T,int> Xi; 

This was later revised in N1449 by Gabriel Dos Reis and Mat Marcus. They adopt the using syntax, and note the following:

Note that we specifically avoid the term “typedef template” and introduce the new syntax involving the pair “using” and “=” to help avoid confusion: we are not defining any types here, we are introducing a synonym (i.e. alias) for an abstraction of a type-id (i.e. type expression) involving template parameters.

They also state:

Two straw polls were taken regarding syntax. A strong majority voted to avoid the typedef template syntax, in favor of the “=” syntax. A second vote indicated strong preference for the “using” keyword as opposed to a word like “alias” or the absence of any keyword as in the draft version of this proposal. The motivation for using any keyword at all stemmed partly from the desire to use a syntax that might be compatible with the non-template aliasing direction briefly outlined above.

This syntax was then adopted in the final proposal N2258 by Gabriel Dos Reis and Bjarne Stroustrup.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • 2
    You could also mention that there's been a discussion about the semantics of alias templates, N1406/2.2 "The Main Choice: Specialization vs. Everything Else". The `using =` reflects the semantics on a syntax level. – dyp Jul 23 '14 at 17:18
  • A template *is* a parameterized type. Stroustroup himself even stated that in a paper back in 1989 [https://www.usenix.org/legacy/publications/compsystems/1989/win_stroustrup.pdf]. So, I would argue that it *is* creating a new type or family of types. But, I actually do like the new syntax, so I'm not complaining any more than I would usually complain about C++ being overcomplicated. – jtchitty Oct 21 '16 at 01:09