| Start |
|---|
| Function Templates Templating can also be applied to functions (as well as the more traditional structures) with the same effect. This can then be used in the same way as structure templates. In both these case the template argument is used to replace the types of the parameters; the result works just like a normal C++ function (if the parameters don't match the template type the compiler applies the standard conversions). One additional property of template functions (unlike template classes) is that the compiler can infer the template parameters based on the parameters passed to the function. This feature allows us to simplify code when we combine template structures and functions. There is a common pattern in the standard library that allows us to make How does this help? Note: This is not designed to shorten the code. This is designed to make the code more robust. It allows the types to be changed by changing the code in a single place rather than in multiple locations. |
| Basic Class Template The basic idea of a class template is that the template parameter gets substituted by a type at compile time. The result is that the same class can be reused for multiple types. The user specifies which type will be used when a variable of the class is declared. Three examples of this are shown in |
| Variadic template data structures It is often useful to define classes or structures that have a variable number and type of data members which are defined at compile time. The canonical example is This already allows us to define an empty structure, Next comes the recursive case specialisation: This is now sufficient for us to create arbitrary data structures, like So what's going on? First, note that this is a specialisation whose requirement is that at least one variadic template parameter (namely To understand this better, we can work through an example: suppose you have a declaration You can visualise this as follows: Now we have the data structure, but its not terribly useful yet as we cannot easily access the individual data elements (for example to access the last member of As you can see this So on to the helper class. This time we will need an empty forward declaration and two specialisations. First the declaration: Now the base-case (when In the recursive case, we decrement To work through an example, suppose we have So that's it! Here is the whole functioning code, with some example use in the |
| Argument forwarding Template may accept both lvalue and rvalue references using forwarding reference: In this case, the real type of In the first case, the type Note: It is worth noticing that in the first case, In order to perfectly forward Forwarding references may be used with variadic templates: Note: Forwarding references can only be used for template parameters, for instance, in the following code, |
| Template Specialization You can define implementation for specific instantiations of a template class/method. For example if you have: You can then write: Then a user that writes |
| Partial template specialization In contrast of a full template specialization partial template specialization allows to introduce template with some of the arguments of existing template fixed. Partial template specialization is only available for template class/structs: As shown above, partial template specializations may introduce completely different sets of data and function members. When a partially specialized template is instantiated, the most suitable specialization is selected. For example, let's define a template and two partial specializations: Now the following calls: will print Function templates may only be fully specialized: |
| Alias template Basic example: This definition makes Alias templates cannot be specialized. However, that functionality can be obtained indirectly by having them refer to a nested type in a struct: |
| Template template parameters Sometimes we would like to pass into the template a template type without fixing its values. This is what template template parameters are created for. Very simple template template parameter examples: |
| Declaring non-type template arguments with auto Prior to C++17, when writing a template non-type parameter, you had to specify its type first. So a common pattern became writing something like: But for complicated expressions, using something like this involves having to write Empty custom deleter for unique_ptrA nice motivating example can come from trying to combine the empty base optimization with a custom deleter for And now you can simply use any function pointer that can take an argument of type |
| Non-type template parameter Apart from types as a template parameter we are allowed to declare values of constant expressions meeting one of the following criteria:
Like all template parameters, non-type template parameters can be explicitly specified, defaulted, or derived implicitly via Template Argument Deduction. Example of non-type template parameter usage: Example of explicitly specifying both type and non-type template parameters: Non-type template parameters are one of the ways to achieve template recurrence and enables to do Metaprogramming (opens new window). |
| Explicit instantiation An explicit instantiation definition creates and declares a concrete class, function, or variable from a template, without using it just yet. An explicit instantiation can be referenced from other translation units. This can be used to avoid defining a template in a header file, if it will only be instantiated with a finite set of arguments. For example: Because If an explicit instantiation definition is preceded by the
|
| Default template parameter value Just like in case of the function arguments, template parameters can have their default values. All template parameters with a default value have to be declared at the end of the template parameter list. The basic idea is that the template parameters with default value can be omitted while template instantiation. Simple example of default template parameter value usage: Syntax
RemarksThe word Before C++11, a template could be declared with the
Due to difficulty of implementation, the |
Read Article
https://develop.horje.com/learn/1434/reference