typedef vs using in Templates

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

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.

Type Aliases

Learn how to use type aliases and utilities to simplify working with complex types.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Performance Impact of Type Aliases
Are there any performance implications of using type aliases?
Type Aliases with Function Pointers
Can I use type aliases with function pointers? How?
Type Aliases with Const and Volatile
How do type aliases interact with const and volatile qualifiers?
Naming Conventions for Type Aliases
What are the best practices for naming type aliases?
Type Aliases with Auto-Deduced Types
Are there any limitations to using type aliases with auto-deduced types?
Platform-Specific Type Aliases
Can I use type aliases to create platform-specific type definitions?
Type-Safe Enum Pattern with Aliases
How can I use type aliases to implement a type-safe enum pattern in C++?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant