Like it!

Join us on Facebook!

Like it!

The differences between "using" and "typedef" in modern C++

Two ways of defining type aliases for a smarter code.

Since the beginning of C you can add synonyms to types that otherwise would be too complex or not much meaningful to work with. In a nutshell, you give an existing type, e.g. int, a new name, e.g. Pixel. Known as type aliases, they help you keep your code clean, short and understandable.

Say for example you are working with a graphical library. Compare the following two functions:

int getScreenWidth();

// Or ... 

Pixel getScreenWidth();

The latter is clearly more intuitive: having declared the alias Pixel it is obvious what this function is about. Another example:

std::map<std::string, std::vector<std::string>> map;

// Or ... 

Map map;

I think you get the picture.

However keep in mind that a type alias does not create a new type: it only generates a synonym, or another way of calling the underlying one. The alias Pixel is still an int and Map is still that frightening std::map<std::string, std::vector<std::string>> and they can be used with functions that accept ints and std::map<std::string, std::vector<std::string>>s as inputs.

Declaring new aliases

There are two ways of declaring new type aliases in modern C++. The first and traditional one is with the typedef keyword:

typedef [original-type] [your-alias];

For example:

typedef int Pixel;
typedef std::map<std::string, std::vector<std::string>> Map;

The other one, introduced in C++11, is with the using keyword:

using [your-alias] = [original-type];

For example

using Pixel = int;
using Map   = std::map<std::string, std::vector<std::string>>;

The result is identical: either way you will end up with new names Pixel and Map that you can use everywhere you need. But...

using works best with templates

The alias Map created in the two examples above (both with typedef and using) has its original type set in stone: it will always be a std::map<std::string, std::vector<std::string>> and there is no way to change it, for example into a std::map<int, std::vector<int>>, unless you declare a new alias with that type.

Fortunately the C++11's using has the ability to create the so-called alias template: an alias that keeps an open door to the underlying type. You can have the usual type aliasing and the ability to specify the template parameter(s) in the future.

This is how to declare an alias template:

template<[template-parameter-list]> using [your-alias] = [original-type];

For example:

template<typename T1, typename T2> using Map = std::map<T1, std::vector<T2>>;

Now I can define new Map variables of different types:

// Actual type: std::map<std::string, std::vector<std::string>> (as in the original example)
Map<std::string, std::string> map1;

// Actual type: std::map<int, std::vector<int>>
Map<int, int> map2;

// Actual type: std::map<int, std::vector<float>>
Map<int, float> map3;

Such behavior could be replicated with the traditional typedef, but it's way trickier and it's not worth it.

A template declaration cannot appear at block scope

You can put type alias declarations — both performed with typedef or using — everywhere you wish: in namespaces, in classes and inside blocks (i.e. between { and }).

Alias templates on the other hand follow the same rules of any other templated thing in C++: they cannot appear inside a block. They are actual template declarations, after all!

Sources

cprogramming.com - The Typedef Keyword in C and C++
cppreference.com - Type alias, alias template
cppreference.com - typedef specifier
StackOverflow - What is the difference between 'typedef' and 'using' in C++11?

comments
fred on June 07, 2019 at 11:14
Thank you it was short but very clear
Will on October 18, 2019 at 21:41
Great explanation. Right to the point
Ginger9 on December 29, 2019 at 09:30
clear explanation, helps a lot
SimonA on January 20, 2020 at 12:35
?Typo? You write: 'The alias ..., for example into a std::map>, unless you don't declare a new alias with that type.'
-- 'unless you don't' --?
Triangles on January 21, 2020 at 10:31
@SimonA thanks, typo fixed!
sanjeev on February 05, 2021 at 08:29
clear explanation. easy to grasp
Ron on March 10, 2021 at 15:00
Thanks just what I was looking for
Steving on November 20, 2022 at 11:42
Thank you, very clear and useful with good examples.