Reader small image

You're reading from  Modern C++ Programming Cookbook - Third Edition

Product typeBook
Published inFeb 2024
PublisherPackt
ISBN-139781835080542
Edition3rd Edition
Right arrow
Author (1)
Marius Bancila
Marius Bancila
author image
Marius Bancila

Marius Bancila is a software engineer with two decades of experience in developing solutions for line of business applications and more. He is the author of The Modern C++ Challenge and Template Metaprogramming with C++. He works as a software architect and is focused on Microsoft technologies, mainly developing desktop applications with C++ and C#. He is passionate about sharing his technical expertise with others and, for that reason, he has been recognized as a Microsoft MVP for C++ and later developer technologies since 2006. Marius lives in Romania and is active in various online communities.
Read more about Marius Bancila

Right arrow

Creating type aliases and alias templates

In C++, it is possible to create synonyms that can be used instead of a type name. This is achieved by creating a typedef declaration. This is useful in several cases, such as creating shorter or more meaningful names for a type or names for function pointers. However, typedef declarations cannot be used with templates to create template type aliases. An std::vector<T>, for instance, is not a type (std::vector<int> is a type), but a sort of family of all types that can be created when the type placeholder T is replaced with an actual type.

In C++11, a type alias is a name for another already declared type, and an alias template is a name for another already declared template. Both of these types of aliases are introduced with a new using syntax.

How to do it...

  • Create type aliases with the form using identifier = type-id, as in the following examples:
    using byte     = unsigned char;
    using byte_ptr = unsigned char *;
    using array_t  = int[10];
    using fn       = void(byte, double);
    void func(byte b, double d) { /*...*/ }
    byte b{42};
    byte_ptr pb = new byte[10] {0};
    array_t a{0,1,2,3,4,5,6,7,8,9};
    fn* f = func;
    
  • Create alias templates with the form template<template-params-list> identifier = type-id, as in the following examples:
    template <class T>
    class custom_allocator { /* ... */ };
    template <typename T>
    using vec_t = std::vector<T, custom_allocator<T>>;
    vec_t<int>           vi;
    vec_t<std::string>   vs;
    

For consistency and readability, you should do the following:

  • Not mix typedef and using declarations when creating aliases
  • Prefer the using syntax to create names of function pointer types

How it works...

A typedef declaration introduces a synonym (an alias, in other words) for a type. It does not introduce another type (like a class, struct, union, or enum declaration). Type names introduced with a typedef declaration follow the same hiding rules as identifier names. They can also be redeclared, but only to refer to the same type (therefore, you can have valid multiple typedef declarations that introduce the same type name synonym in a translation unit, as long as it is a synonym for the same type). The following are typical examples of typedef declarations:

typedef unsigned char   byte;
typedef unsigned char * byte_ptr;
typedef int             array_t[10];
typedef void(*fn)(byte, double);
template<typename T>
class foo {
  typedef T value_type;
};
typedef std::vector<int> vint_t;
typedef int INTEGER;
INTEGER x = 10;
typedef int INTEGER; // redeclaration of same type
INTEGER y = 20;

A type alias declaration is equivalent to a typedef declaration. It can appear in a block scope, class scope, or namespace scope. According to C++11 standard (paragraph 9.2.4, document version N4917):

A typedef-name can also be introduced by an alias declaration. The identifier following the using keyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. It has the same semantics as if it were introduced by the typedef specifier. In particular, it does not define a new type and it shall not appear in the type-id.

An alias declaration is, however, more readable and clearer about the actual type that is aliased when it comes to creating aliases for array types and function pointer types. In the examples from the How to do it... section, it is easily understandable that array_t is a name for the type array of 10 integers, while fn is a name for a function type that takes two parameters of the type byte and double and returns void. This is also consistent with the syntax for declaring std::function objects (for example, std::function<void(byte, double)> f).

It is important to take note of the following things:

  • Alias templates cannot be partially or explicitly specialized.
  • Alias templates are never deduced by template argument deduction when deducing a template parameter.
  • The type produced when specializing an alias template is not allowed to directly or indirectly make use of its own type.

The driving purpose of the new syntax is to define alias templates. These are templates that, when specialized, are equivalent to the result of substituting the template arguments of the alias template for the template parameters in the type-id.

See also

  • Simplifying code with class template argument deduction, to learn how to use class templates without explicitly specifying template arguments
Previous PageNext Page
You have been reading a chapter from
Modern C++ Programming Cookbook - Third Edition
Published in: Feb 2024Publisher: PacktISBN-13: 9781835080542
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Marius Bancila

Marius Bancila is a software engineer with two decades of experience in developing solutions for line of business applications and more. He is the author of The Modern C++ Challenge and Template Metaprogramming with C++. He works as a software architect and is focused on Microsoft technologies, mainly developing desktop applications with C++ and C#. He is passionate about sharing his technical expertise with others and, for that reason, he has been recognized as a Microsoft MVP for C++ and later developer technologies since 2006. Marius lives in Romania and is active in various online communities.
Read more about Marius Bancila