using vs typedef in C++

Jay Shaw Oct 12, 2023
  1. the using Keyword in C++
  2. the typedef Keyword in C++
  3. Use of typedef and using in Defining Templates
  4. Conclusion
using vs typedef in C++

This article tries to distinguish between typedef and using. In C++ functional programming, these keywords have the same purpose and semantics, leaving a very narrow line of difference between them.

This article will explain the keywords in different contexts to ensure the reader understands what these keywords do and the differences between typedef and using.

the using Keyword in C++

Understanding the using keyword in contrast to typedef is important to learn the differences between typedef and using.

It is used to bring objects to the current scope of the program. This means it can be used as an access tool to bring specifiers from C++.

Let’s look at an example.

#include <iostream>

int main() {
  using std::cout;
  using std::string;

  int a = 56;
  cout << a;
  return 0;
}

Output:

56

Here, the keyword using is used to access specifiers like cout and string from the namespace and bring them inside the program’s scope.

Similarly, using can also be used to access other specifiers or bring the whole namespace by using - using namespace as std. This brings the entire namespace inside the program’s scope, and every specifier can be accessed using std.

Example for using Keyword

The code snippet below creates a class Parent with a public method add having two integer variables a and b as parameters. The method add prints the summation of the two variables.

The child class derives the Parent class in protected mode, which means all the members of the Parent class will be inherited as protected members.

Inside the main function, an instance of the object is created using the Child class, and the method add is derived using that object.

#include <iostream>
using namespace std;
class Parent {
 public:
  void add(int a, int b) { cout << "Result = " << a + b << endl; }
};
class Child : protected Parent {
 public:
  using Parent::add;
};
int main() {
  Child obj;
  obj.add(15, 30);
  return 0;
}

Output:

Result = 45

Here, the keyword using is used to access the method add from the Parent class through its Child class.

Implement Loops With using Keyword in C++

The syntax here implements the for loop through using.

for (using i = int; i{} != 0;) {
  i++;
}

In the case of range-based loops, using is used as follows:

std::vector<int> v{1, 2, 3};
for (using Foo = int; Foo f : v) {
  (void)f;
}

Switch Case Statements With using Keyword in C++

In switch case statements, using is implemented as:

if (using Foo = int; true) {
  (void)Foo{};
}
switch (using Foo = int; 0) {
  case 0:
    (void)Foo{};
}

the typedef Keyword in C++

The keyword typedef has the function to name a type using a custom name. This means an alias can be introduced for an existing datatype.

Major differences between typedef and using can be observed in this section.

The program below explains this concept clearly.

#include <stdio.h>
#include <string.h>

typedef struct Books {
  char title[50];
  char author[50];
  char subject[100];
  int book_id;
} Book;

A struct class Book is introduced, which has four variables. These four variables are structured as a new datatype using typedef, and this type is given the name Book.

Inside the main class, a new object must be created to access the type Book and fetch its variables (as per requirement).

It can be observed that the individual variables are called using the syntax object_name.variable_name,"input". Once these variables are given data, it is printed using the same method used to call it.

int main() {
  Book book;

  strcpy(book.title, "Typedef vs using");
  strcpy(book.author, "JS");
  strcpy(book.subject, "C Programming");
  book.book_id = 6495407;

  printf("Book title : %s\n", book.title);
  printf("Book author : %s\n", book.author);
  printf("Book subject : %s\n", book.subject);
  printf("Book book_id : %d\n", book.book_id);

  return 0;
}

Output:

Book title : Typedef vs using
Book author : JS
Book subject : C Programming
Book book_id : 6495407

Loops Using typedef Keyword in C++

During the loop iteration, typedef is defined using syntax for (typedef (datatype)Function; Function{} != 0;).

for (typedef int i; i{} != 0;) {
  i++;
}

During a range-based loop iteration, typedef is used as:

std::vector<int> v{1, 2, 3};
for (typedef int Foo; Foo f : v)
//   ^^^^^^^^^^^^^^^ init-statement
{
  (void)f;
}

Another example of a range-based loop inside a 2-D matrix:

for (typedef struct {
       int x;
       int y;
     } P;
     auto [x, y] : {P{1, 1}, {1, 2}, {3, 5}}) {
  (void)x;
  (void)y;
}

Switch Case Statements Using typedef Keyword in C++

The typedef keyword is used in switch case statements, as shown below.

if (typedef int Foo; true) {
  (void)Foo{};
}

switch (typedef int Foo; 0) {
  case 0:
    (void)Foo{};
}

Use of typedef and using in Defining Templates

We’ve observed differences between typedef and using from the context of functional programming. Another important part that needs to be understood is how to define templates.

In C++, typedefs had the function of defining aliases for templates. It has been used for a very long time, but it was observed that the semantics of typedef does not go well with templates.

To resolve the issue, typedef has been depreciated, and using has taken place.

In the below examples, differences between typedef and using are discussed in the context of defining templates.

Aliasing Template With typedef in C++

Example 1:

Here, a rectangle has been defined as having an x length and a static breadth which needs to be given an alias using templates.

The <size_t N> is a template that stores the length of the rectangle. In contrast, Dimension is an object that will be given the alias Rectangle using typedef.

Here, the code assigns the Rectangle to be an alias of Dimension<N,1>, which means the object Dimension will have a length and a breadth. Here, the object Dimension has a length <size_t N> and breadth of 1.

template <size_t N>
struct Rectangle {
  typedef Dimension<N, 1> type;
};

This implies that the programmer needs to pass a single value parameter, size_t N to the Rectangle. The compiler will take that passed as the length, while the breadth is set at 1.

The syntax Rectangle<5>::int passes integer value 5 to object Dimension and it will be the same as writing Dimension<5,1>.

The above examples are no more used in the recent C++ version as typedef is depreciated. Taking the use of using to give an alias to templates is simpler than the above example.

Example 2:

The template class Match is defined in the code snippet below. This Match class is given an alias template MatchBox.

The Match class can be substituted in the future too.

template <typename U>
struct Match {};

template <typename U>
struct MatchBox {
  typedef Match<U> type;
};

MatchBox<int>::type variable;

template <typename V>
struct bar {
  typename MatchBox<V>::type_var_member;
}

If type abstraction is required, but the template parameter also needs to be preserved so that it may be provided in the future, this is the kind of code that ought to be written.

Aliasing Templates With using Keyword in C++

Example 1:

This section draws differences between typedef and using in the context of templates. Here, the template <size_t N> is the same as the one used in the typedef example 1, which stores the length of the rectangle.

Instead of using struct, the alias Rectangle is assigned to the object Dimension through the keyword using. This is done in the same way as an operator is assigned.

The alias Rectangle after assignment of alias has N and 1 as length and breadth, respectively.

template <size_t N>
using Rectangle = Dimension<N, 1>;

It can be observed that using provides a more refined version of aliasing, which is easier to write and implement. The readability of the syntax used here seems improved because it is now more like the conventional assignment of variables and operators.

Example 2:

This example keeps the template parameter open so that specifying it remains possible. In the typedef example, this process required multiple lines of codes. But the using syntax reduces code and complexity.

template <typename U>
using MatchBox = Match < U

                             MatchBox<int>
                                 variable;
template <typename V>
struct bar {
  MatchBox<V> _var_member;
}

Using the using keyword to define an alias for templates is far easier than typedef because the process is similar to copy assignment of variables.

Conclusion

This article covers the differences between keywords typedef and using in C++. The reader will understand these keywords’ basic differences and implementation in different programming contexts.

It is hoped that this article helped in your learning journey.