×

Search anything:

typedef vs using in C++

Binary Tree book by OpenGenus

Open-Source Internship opportunity by OpenGenus for programmers. Apply now.

typedef and using in C++: Two ways to a cleaner code

Table of contents:

  1. Introduction
  2. Declaring Aliases
  3. Key Differences
  4. Conclusion

Introduction

In this article, we will explore the differences between the two type aliases in C++ - typedef and using.

  • In a nutshell, you rename an existing type, such as int, to Photo.
    They assist you with writing code that is clear, concise, and easy to understand.

Consider the following example,
While working in a library, two functions are created

int getLength();
Photo getLength();

The latter appears to be the more natural choice: having declared the alias Photo it becomes obvious what the function is about.
It should be reiterated, however, that a type alias doesn't really create a new type; instead, it defines a synonym or another way of calling the underlying one.

  • New type declarations like union, class, etc. aren't introduced by 'typedef'. Instead, existing types are given new names that are in the same namespace as other identifiers.

  • The 'typedef' declarations have worked well and have been sufficient for the most part, but they do have shortcomings, evident especially when it comes to using templates. In the following sections, we'll look at such constraints and how the 'using' statement addresses them.

Declaring Aliases

A programmer in modern C++ has two options for declaring new type aliases.

The typedef keyword is used to declare new type aliases in the typical way.

typedef [original-type] [alias];

EXAMPLE

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

The using keyword is the new means of declaring new type aliases introduced in C++11.

using [alias] = [original-type];

EXAMPLE

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

The end result is the same in both cases: two aliases Photo and Map are formed that can be used everywhere.

Key Differences

  1. One of the key differentiators between using and typedef in C++ is that 'using' can perform all of the functions that 'typedef' can, as well as allowing the programmer to work with templates relatively efficiently.
    The alias Map has a fixed type: it will always be a std::map<std::string, std::vector< std::string >> and there is no way to covert it to something other, for example into a std::map<int, std::vector<int>>, unless you declare a new alias with that type.

The use of C++11 allows you to construct an alias template, which is an alias that maintains an open door to the underlying type. You can use conventional type aliasing while also having the option to define the template parameter(s) afterwards.

Syntax for declaring an alias template

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

For example:

template<typename TA, typename TB> using Map = std::map<TA, std::vector<TB>>;

Now, new map variables of different types can be defined as under:

// Actual type: std::map<std::string, std::vector<std::string>>
Map<std::string, std::string> mapA;
// Actual type: std::map<int, std::vector<int>>
Map<int, int> mapB;
// Actual type: std::map<int, std::vector<float>>
Map<int, float> mapC;

The traditional typedef might be used to duplicate this behaviour, but it's much more difficult.

  1. From the programmer's point of view, working with "using" statement is very simple and clear, especially when working with function pointers and their alias definition. In fact, the 'using' statement provides more code readability, as shown in the following example:
typedef void(*func_pointer)(int);
using func_pointer = void(*)(int);
  1. Alias declarations made using both the 'using' and 'typedef' statements can be made everywhere in the code, including in classes, namespaces, and blocks, but template declarations done by only the 'using' statement cannot be declared inside a class.

  2. The declaration for the generic alias must always be wrapped in the struct in the case of 'typedef', unlike the 'using' statement, which does not require wrapping.

template<typename T>
using Account = std::unordered_map<Admission_No, std::vector<T>>;
Vs
template<typename T>
struct Account {
typedef std::map<Admission_No, std::vector<T>> type;
};
//Using the above like:
Account<AdmissionAccount>::type AdmissionDetailsAccount;
  1. It is possible to declare the same variable using typedef in 2 different files and no error will be thrown as long as they both refer to the same type. This is not valid with using keyword.

  2. Unlike the 'using' statement, 'typedef' enables the programmer to designate numerous type aliases at once.

 typedef int x, *ptr, (*Fun)();   

Conclusion

When it comes to defining the simpler type aliases, choosing between typedef and using could be a matter of personal choice. The major limitation of typedef is that it does not work with templates. Both using and typedef perform the same mechanically while working with non-templates. However, while defining the more complex template aliases, function-pointer aliases, and array reference aliases, the using statement emerges as a clear winner.

With this article at OpenGenus, you must have the complete idea of typedef vs using in C++.

typedef vs using in C++
Share this