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 illegalWith 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: 2This 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>: trueConclusion
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.