Type Aliases

typedef vs using in Templates

What's the difference between type aliases and typedefs in terms of template support?

Illustration representing computer hardware

The main difference between type aliases (introduced with the using keyword in C++11) and typedefs in terms of template support is that type aliases can be templated, while typedefs cannot. This makes type aliases more flexible and powerful when working with templates. Let's explore this in detail.

Basic Syntax

First, let's review the basic syntax for both:

// typedef syntax
typedef std::vector<int> IntVector;

// using syntax (type alias)
using IntVector = std::vector<int>;

For simple cases like this, both typedef and using are equivalent.

Template Support

The key difference emerges when we want to create a template alias:

#include <iostream>
#include <vector>

// This is possible with using
template <typename T>
using Vec = std::vector<T>;

// This is not possible with typedef
template<typename T>
typedef std::vector<T> Vec;  

int main() {
  Vec<int> v{1, 2, 3};
  for (const auto& i : v) {
    std::cout << i << ' ';
  }
}
error: a typedef template is illegal

With using, we can create a template alias Vec that can be used with any type. This is not possible with typedef.

Complex Template Aliases

Type aliases really shine when dealing with more complex template types:

#include <iostream>
#include <map>
#include <string>

template <typename Key, typename Value>
using MapWithDefault = std::map<
  Key, Value, std::less<Key>,
  std::allocator<std::pair<const Key, Value>>
>;

int main() {
  MapWithDefault<std::string, int> myMap;
  myMap["one"] = 1;
  myMap["two"] = 2;

  for (const auto& [key, value] : myMap) {
    std::cout << key << ": " << value << '\n';
  }
}
one: 1
two: 2

This kind of template alias would be much more cumbersome to express with typedef.

Partial Specialization

Type aliases also allow for partial specialization, which isn't possible with typedef:

#include <iostream>
#include <type_traits>

template <typename T>
using RemoveConst = typename std::remove_const<T>::type;

template <typename T>
using AddConst = typename std::add_const<T>::type;

int main() {
  std::cout << std::boolalpha;
  std::cout
    << "int is same as RemoveConst<const int>: "
    << std::is_same_v<int, RemoveConst<const int>>;
  std::cout
    << "\nconst int is same as AddConst<int>: "
    << std::is_same_v<const int, AddConst<int>>;
}
int is same as RemoveConst<const int>: true
const int is same as AddConst<int>: true

Conclusion

While typedef and using are equivalent for simple type aliases, using provides superior template support. This makes using more versatile and generally preferred in modern C++ code, especially when working with templates.

The ability to create template aliases with using can lead to more readable and maintainable code, particularly when dealing with complex template types. For these reasons, using is generally recommended over typedef in new C++ code, especially when template support might be needed.

This Question is from the Lesson:

Type Aliases

Learn how to use type aliases, using statements, and typedef to simplify or rename complex C++ types.

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Type Aliases

Learn how to use type aliases, using statements, and typedef to simplify or rename complex C++ types.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved