The synonyms or typedef
declarations are omnipresent in C++ codebases. They make the code readable and easier to maintain. Since C++11, we can create synonyms or aliases with either typedef
or using
keywords. These are some examples of defining aliases:
//aliases with typedef
typedef std::string identifier_t;
typedef std::map<int,int> mymap_t;
//aliases with 'using'
using identifier_t = std::string;
using mymap_t = std::map<int,int>;
The synonyms created by the using
keywords are called alias-declarations. One of the advantages of alias-declaration over the typedef
is that the alias-declaration can be templatized, called alias-templates. Here is an example of alias-template:
template<typename T>
using VectorOfSets = std::vector<std::set<T>>;
VectorOfSets<int> vs;
One of the motivating examples of alias-templates is creating a pointer template, as shown below:
template<typename T>
using Ptr = T*;
We can use the above pointer template to declare a pointer:
struct Foo { /*...*/ };
void func(Ptr<int> pi) { /*...*/ } //A function parameter
Ptr<Foo> pf = new Foo(); //A Foo*
Ptr<int> pi = new int[100]; //An int*
func(pi); //Pass as argument
auto pc = (Ptr<char>)pi; //cast
Here is the question. A pointer 'p' is defined as int* const
such that the pointer itself cannot point to another address once initialized:
int* const p = new int[100];
p = new int[100]; //ERROR
How can we define 'p' using the Ptr template? Select all the correct choices below (check Explanations
for details):
The pointer template is simply one of the many compelling use cases of alias-templates. Another common application of alias-template is to hide template parameters:
//hide the key type
template<typename T>
using Map = std::map<int, T>;
//Create a std::map<int,std::string>
Map<std::string> mapStrings;
The article 'How C++ using or alias-declaration is better than typedef' covers the benefits of alias-declaration over typedef
.