Showing posts with label template. Show all posts
Showing posts with label template. Show all posts

Saturday, January 18, 2014

specialization of class template c++

Specializations of Class Templates : templates tutorial ccplusplus.com
You can specialize a class template for certain template arguments. Similar to the overloading of function templates, specializing class templates allows you to optimize implementations for certain types or to fix a misbehavior of certain types for an instantiation of the class template. However, if you specialize a class template, you must also specialize all member functions. Although it is possible to specialize a single member function, once you have done so, you can no longer specialize the whole class.
To specialize a class template, you have to declare the class with a leading template<> and a specification of the types for which the class template is specialized. The types are used as a template argument and must be specified directly following the name of the class:




For these specializations, any definition of a member function must be defined as an "ordinary" member function, with each occurrence of T being replaced by the specialized type:




Here is a complete example of a specialization of Stack<> for type std::string:




In this example, a deque instead of a vector is used to manage the elements inside the stack. Although this has no particular benefit here, it does demonstrate that the implementation of a specialization might look very different from the implementation of the primary template.
In fact, there is a benefit for using a deque instead of a vector to implement a stack: A deque frees memory when elements are removed, and it can't happen that elements have to be moved as a result of reallocation. However, this is no particular benefit for strings. For this reason it is probably a good idea to use a deque in the primary class template (as is the case in class std::stack<> of the C++ standard library).








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

using class template c++

Use of Class Template : templates tutorial ccplusplus.com
To use an object of a class template, you must specify the template arguments explicitly. The following example shows how to use the class template Stack<>:




By declaring type Stack<int>, int is used as type T inside the class template. Thus, intStack is created as an object that uses a vector of ints as elements and, for all member functions that are called, code for this type is instantiated. Similarly, by declaring and using Stack<std::string>, an object that uses a vector of strings as elements is created, and for all member functions that are called, code for this type is instantiated.
Note that code is instantiated only for member functions that are called. For class templates, member functions are instantiated only when they are used. This, of course, saves time and space. It has the additional benefit that you can instantiate a class even for those types that cannot perform all the operations of all the member functions, as long as these member functions are not called. As an example, consider a class in which some member functions use the operator < to sort elements. If you refrain from calling these member functions, you can instantiate the class template for types for which operator < is not defined.
In this example, the default constructor, push(), and top() are instantiated for both int and strings. However, pop() is instantiated only for strings. If a class template has static members, these are instantiated once for each type.
You can use a type of an instantiated class template as any other type, as long as the operations are supported:




By using a type definition, you can make using a class template more convenient:



Note that in C++ a type definition does define a "type alias" rather than a new type. Thus, after the type definition




IntStack and Stack<int> are the same type and can be used for and assigned to each other.
Template arguments may be any type, such as pointers to floats or even stacks of ints:




The only requirement is that any operation that is called is possible according to this type.
Note that you have to put whitespace between the two closing template brackets. If you don't do this, you are using operator >>, which results in a syntax error:













-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

declaration of class template

Implementation of the class template : templates tutorial ccplusplus.com
As we did with function templates, we declare and define class Stack<> in a header file as follows




As you can see, the class template is implemented by using a class template of the C++ standard library: vector<>. As a result, we don't have to implement memory management, copy constructor, and assignment operator, so we can concentrate on the interface of this class template.

Declaration of Class Templates

Declaring class templates is similar to declaring function templates: Before the declaration, a statement declares an identifier as a type parameter. Again, T is usually used as an identifier:




Here again, the keyword class can be used instead of typename:




Inside the class template, T can be used just like any other type to declare members and member functions. In this example, T is used to declare the type of the elements as vector of Ts, to declare push() as a member function that gets a constant T reference as an argument, and to declare top() as a function that returns a T:




The type of this class is Stack<T>, with T being a template parameter. Thus, you have to use Stack<T> whenever you use the type of this class in a declaration. If, for example, you have to declare your own copy constructor and assignment operator, it looks like this:
According to the standard, there are some exceptions to this rule. However, to be sure, you should always write the full type when the type is required.




However, when the name and not the type of the class is required, only Stack has to be used. This is the case when you specify the name of the class, the constructors, and the destructor.

Implementation of Member Functions

To define a member function of a class template, you have to specify that it is a function template, and you have to use the full type qualification of the class template. Thus, the implementation of the member function push() for type Stack<T> looks like this:




In this case, push_back() of the element vector is called, which appends the element at the end of the vector.
Note that pop_back() of a vector removes the last element but doesn't return it. The reason for this behavior is exception safety. It is impossible to implement a completely exception-safe version of pop() that returns the removed element. However, ignoring this danger, we could implement a pop() that returns the element just removed. To do this, we simply use T to declare a local variable of the element type:




Because the vectors back() (which returns the last element) and pop_back() (which removes the last element) have undefined behavior when there is no element in the vector, we have to check whether the stack is empty. If it is empty, we throw an exception of type std::out_of_range. This is also done in top(), which returns but does not remove the top element:




Of course, as for any member function, you can also implement member functions of class templates as an inline function inside the class declaration. For example:












-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------
-----------------------------------------------------------------

class template in c++

class template in c++ : templates tutorial ccplusplus.com
Similar to functions, classes can also be parameterized with one or more types. Container classes, which are used to manage elements of a certain type, are a typical example of this feature. By using class templates, you can implement such container classes while the element type is still open. In the coming post we use a stack as an example of a class template.








one definition rule in c++

one definition rule in c++ : templates tutorial ccplusplus.com
The C++ language definition places some constraints on the redeclaration of various entities. The totality of these constraints is known as the one-definition rule or ODR. The details of this rule are quite complex and span a large variety of situations. Later posts illustrate the various resulting facets in each applicable context, and. For now, it suffices to remember the following ODR basics:
  • Noninline functions and member functions, as well as global variables and static data members should be defined only once across the whole program.
  • Class types (including structs and unions) and inline functions should be defined at most once per translation unit, and all these definitions should be identical.
A translation unit is what results from preprocessing a source file; that is, it includes the contents named by #include directives.

In the remainder of this book, linkable entity means one of the following: a noninline function or member function, a global variable or a static data member, including any such things generated from a template.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

overloading function templates in c++

Overloading Function Templates C++ : templates tutorial ccplusplus.com
Like ordinary functions, function templates can be overloaded. That is, you can have different function definitions with the same function name so that when that name is used in a function call, a C++ compiler must decide which one of the various candidates to call. The rules for this decision may become rather complicated, even without templates. In this section we discuss overloading when templates are involved. If you are not familiar with the basic rules of overloading without templates.
The following short program illustrates overloading a function template:




As this example shows, a nontemplate function can coexist with a function template that has the same name and can be instantiated with the same type. All other factors being equal, the overload resolution process normally prefers this nontemplate over one generated from the template. The fourth call falls under this rule:




If the template can generate a function with a better match, however, then the template is selected. This is demonstrated by the second and third call of max():




It is also possible to specify explicitly an empty template argument list. This syntax indicates that only templates may resolve a call, but all the template parameters should be deduced from the call arguments:




Because automatic type conversion is not considered for templates but is considered for ordinary functions, the last call uses the nontemplate function (while 'a' and 42.7 both are converted to int):




A more useful example would be to overload the maximum template for pointers and ordinary C-strings:




Note that in all overloaded implementations, we pass all arguments by reference. In general, it is a good idea not to change more than necessary when overloading function templates. You should limit your changes to the number of parameters or to specifying template parameters explicitly. Otherwise, unexpected effects may happen. For example, if you overload the max() template, which passes the arguments by reference, for two C-strings passed by value, you can't use the three-argument version to compute the maximum of three C-strings:




The problem is that if you call max() for three C-strings, the statement




becomes an error. This is because for C-strings, max(a,b) creates a new, temporary local value that may be returned by the function by reference.
This is only one example of code that might behave differently than expected as a result of detailed overload resolution rules. For example, the fact that not all overloaded functions are visible when a corresponding function call is made may or may not matter. In fact, defining a three-argument version of max() without having seen the declaration of a special two-argument version of max() for ints causes the two-argument template to be used by the three-argument version:




As a rule of thumb you should always have all overloaded versions of a function declared before the function is called.








template summary c++

Templates Parameter : templates tutorial ccplusplus.com

template Summary

  • Template functions define a family of functions for different template arguments.
  • When you pass template arguments, function templates are instantiated for these argument types.
  • You can explicitly qualify the template parameters.
  • You can overload function templates.
  • When you overload function templates, limit your changes to specifying template parameters explicitly.
  • Make sure you see all overloaded versions of function templates before you call them.








default template arguments c++

default template arguments c++ : templates tutorial ccplusplus.com
For class templates you can also define default values for template parameters. These values are called default template arguments. They may even refer to previous template parameters. For example, in class Stack<> you can define the container that is used to manage the elements as a second template parameter, using std::vector<> as the default value:


Note that we now have two template parameters, so each definition of a member function must be defined with these two parameters:


You can use this stack the same way it was used before. Thus, if you pass a first and only argument as an element type, a vector is used to manage the elements of this type:


In addition, you could specify the container for the elements when you declare a Stack object in your program:


With



you declare a stack for doubles that uses a std::deque<> to manage the elements internally.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

class template summary c++

Class Templates Summary : templates tutorial ccplusplus.com
class template summary
  • A class template is a class that is implemented with one or more type parameters left open.
  • To use a class template, you pass the open types as template arguments. The class template is then instantiated (and compiled) for these types.
  • For class templates, only those member functions that are called are instantiated.
  • You can specialize class templates for certain types.
  • You can partially specialize class templates for certain types.
  • You can define default values for class template parameters. These may refer to previous template parameters.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

non type template parameters c++

non type template parameters c++ : templates tutorial ccplusplus.com
For function and class templates, template parameters don't have to be types. They can also be ordinary values. As with templates using type parameters, you define code for which a certain detail remains open until the code is used. However, the detail that is open is a value instead of a type. When using such a template, you have to specify this value explicitly. The resulting code then gets instantiated. This chapter illustrates this feature for a new version of the stack class template. In addition, we show an example of nontype function template parameters and discuss some restrictions to this technique.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

c++ template non-class type

c++ template non-class type : templates tutorial ccplusplus.com
In contrast to the sample implementations of a stack in previous chapters, you can also implement a stack by using a fixed-size array for the elements. An advantage of this method is that the memory management overhead, whether performed by you or by a standard container, is avoided. However, determining the best size for such a stack can be challenging. The smaller the size you specify, the more likely it is that the stack will get full. The larger the size you specify, the more likely it is that memory will be reserved unnecessarily. A good solution is to let the user of the stack specify the size of the array as the maximum size needed for stack elements.
To do this, define the size as a template parameter:


The new second template parameter, MAXSIZE, is of type int. It specifies the size of the array of stack elements:


In addition, it is used in push() to check whether the stack is full:


To use this class template you have to specify both the element type and the maximum size:


Note that each template instantiation is its own type. Thus, int20Stack and int40Stack are two different types, and no implicit or explicit type conversion between them is defined. Thus, one cannot be used instead of the other, and you cannot assign one to the other.
Again, default values for the template parameters can be specified:



However, from a perspective of good design, this may not be appropriate in this example. Default values should be intuitively correct. But neither type int nor a maximum size of 100 seems intuitive for a general stack type. Thus, it is better when the programmer has to specify both values explicitly so that these two attributes are always documented during a declaration.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

c++ function template non-type parameter

c++ function template non-type parameter : templates tutorial ccplusplus.com
You can also define nontype parameters for function templates. For example, the following function template defines a group of functions for which a certain value can be added:


These kinds of functions are useful if functions or operations in general are used as parameters. For example, if you use the Standard Template Library (STL) you can pass an instantiation of this function template to add a value to each element of a collection:


The last argument instantiates the function template addValue() to add 5 to an int value. The resulting function is called for each element in the source collection source, while it is translated into the destination collection dest.
Note that there is a problem with this example: addValue<int,5> is a function template, and function templates are considered to name a set of overloaded functions (even if the set has only one member). However, according to the current standard, sets of overloaded functions cannot be used for template parameter deduction. Thus, you have to cast to the exact type of the function template argument:



There is a proposal for the standard to fix this behavior so that the cast isn't necessary in this context , but until then the cast may be necessary to be portable.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

restriction for non type template parameters c++

restriction for non type template parameters c++ : templates tutorial ccplusplus.com

Restrictions for Nontype Template Parameters


Note that nontype template parameters carry some restrictions. In general, they may be constant integral values (including enumerations) or pointers to objects with external linkage.
Floating-point numbers and class-type objects are not allowed as nontype template parameters:


Not being able to use floating-point literals (and simple constant floating-point expressions) as template arguments has historical reasons. Because there are no serious technical challenges, this may be supported in future versions of C++.
Because string literals are objects with internal linkage (two string literals with the same value but in different modules are different objects), you can't use them as template arguments either:


You cannot use a global pointer either:


However, the following is possible:



The global character array s is initialized by "hello" so that s is an object with external linkage.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

Nontype Template Parameters summary

Nontype Template Parameters : templates tutorial ccplusplus.com
Nontype Template Parameters summary
  • Templates can have template parameters that are values rather than types.
  • You cannot use floating-point numbers, class-type objects, and objects with internal linkage (such as string literals) as arguments for nontype template parameters.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

c++ template typename keyword

c++ template typename keyword : templates tutorial ccplusplus.com
The keyword typename was introduced during the standardization of C++ to clarify that an identifier inside a template is a type. Consider the following example:


Here, the second typename is used to clarify that SubType is a type defined within class T. Thus, ptr is a pointer to the type T::SubType.
Without typename, SubType would be considered a static member. Thus, it would be a concrete variable or object. As a result, the expression


would be a multiplication of the static SubType member of class T with ptr.
In general, typename has to be used whenever a name that depends on a template parameter is a type.
A typical application of typename is the access to iterators of STL containers in template code:


In this function template, the call parameter is an STL container of type T. To iterate over all elements of the container, the iterator type of the container is used, which is declared as type const_iterator inside each STL container class:


Thus, to access type const_iterator of template type T, you have to qualify it with a leading typename:


The .template Construct

A very similar problem was discovered after the introduction of typename. Consider the following example using the standard bitset type:


The strange construct in this example is .template. Without that extra use of template, the compiler does not know that the less-than token (<) that follows is not really "less than" but the beginning of a template argument list. Note that this is a problem only if the construct before the period depends on a template parameter. In our example, the parameter bs depends on the template parameter N.

In conclusion, the .template notation (and similar notations such as ->template) should be used only inside templates and only if they follow something that depends on a template parameter.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

this pointer template c++

this pointer template c++ : templates tutorial ccplusplus.com

Using this->

For class templates with base classes, using a name x by itself is not always equivalent to this->x, even though a member x is inherited. For example:


In this example, for resolving the symbol exit inside foo(), exit() defined in Base is never considered. Therefore, either you have an error, or another exit() (such as the standard exit()) is called. For the moment, as a rule of thumb, we recommend that you always qualify any symbol that is declared in a base that is somehow dependent on a template parameter with this-> or Base<T>::. If you want to avoid all uncertainty, you may consider qualifying all member accesses (in templates).








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

member template c++

member template c++ : templates tutorial ccplusplus.com
Class members can also be templates. This is possible for both nested classes and member functions. The application and advantage of this ability can again be demonstrated with the Stack<> class template. Normally you can assign stacks to each other only when they have the same type, which implies that the elements have the same type. However, you can't assign a stack with elements of any other type, even if there is an implicit type conversion for the element types defined:


The default assignment operator requires that both sides of the assignment operator have the same type, which is not the case if stacks have different element types.
By defining an assignment operator as a template, however, you can enable the assignment of stacks with elements for which an appropriate type conversion is defined. To do this you have to declare Stack<> as follows:


The following two changes have been made:
  1. We added a declaration of an assignment operator for stacks of elements of another type T2.
  2. The stack now uses a deque as an internal container for the elements. Again, this is a consequence of the implementation of the new assignment operator.
The implementation of the new assignment operator looks like this:


First let's look at the syntax to define a member template. Inside the template with template parameter T, an inner template with template parameter T2 is defined:


Inside the member function you may expect simply to access all necessary data for the assigned stack op2. However, this stack has a different type (if you instantiate a class template for two different types, you get two different types), so you are restricted to using the public interface. It follows that the only way to access the elements is by calling top(). However, each element has to become a top element, then. Thus, a copy of op2 must first be made, so that the elements are taken from that copy by calling pop(). Because top() returns the last element pushed onto the stack, we have to use a container that supports the insertion of elements at the other end of the collection. For this reason, we use a deque, which provides push_front() to put an element on the other side of the collection.
Having this member template, you can now assign a stack of ints to a stack of floats:


Of course, this assignment does not change the type of the stack and its elements. After the assignment, the elements of the floatStack are still floats and therefore pop() still returns a float.
It may appear that this function would disable type checking such that you could assign a stack with elements of any type, but this is not the case. The necessary type checking occurs when the element of the (copy of the) source stack is moved to the destination stack:


If, for example, a stack of strings gets assigned to a stack of floats, the compilation of this line results in an error message stating that the string returned by tmp.top() cannot be passed as an argument to elems.push_front() (the message varies depending on the compiler, but this is the gist of what is meant):


Note that a template assignment operator doesn't replace the default assignment operator. For assignments of stacks of the same type, the default assignment operator is still called.
Again, you could change the implementation to parameterize the internal container type:


Then the template assignment operator is implemented like this:


Remember, for class templates, only those member functions that are called are instantiated. Thus, if you avoid assigning a stack with elements of a different type, you could even use a vector as an internal container:


Because the assignment operator template isn't necessary, no error message of a missing member function push_front() occurs and the program is fine.
For the complete implementation of the last example, see all the files with a name that starts with "stack6" in the subdirectory basics.

Don't be surprised if your compiler reports errors with these sample files. In the samples, we use almost every important template feature. Thus, you need a compiler that conforms closely to the standard.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------

template template parameters c++

template template parameters c++ : templates tutorial ccplusplus.com
It can be useful to allow a template parameter itself to be a class template. Again, our stack class template can be used as an example.
To use a different internal container for stacks, the application programmer has to specify the element type twice. Thus, to specify the type of the internal container, you have to pass the type of the container and the type of its elements again:


Using template template parameters allows you to declare the Stack class template by specifying the type of the container without respecifying the type of its elements:


To do this you must specify the second template parameter as a template template parameter. In principle, this looks as follows:
There is a problem with this version that we explain in a minute. However, this problem affects only the default value std::deque. Thus, we can illustrate the general features of template template parameters with this example.


The difference is that the second template parameter is declared as being a class template:


The default value has changed from std::deque<T> to std::deque. This parameter has to be a class template, which is instantiated for the type that is passed as the first template parameter:


This use of the first template parameter for the instantiation of the second template parameter is particular to this example. In general, you can instantiate a template template parameter with any type inside a class template.
As usual, instead of typename you could use the keyword class for template parameters. However, CONT is used to define a class and must be declared by using the keyword class. Thus, the following is fine:


but the following is not:


Because the template parameter of the template template parameter is not used, you can omit its name:


Member functions must be modified accordingly. Thus, you have to specify the second template parameter as the template template parameter. The same applies to the implementation of the member function. The push() member function, for example, is implemented as follows:


Template template parameters for function templates are not allowed.

Template Template Argument Matching

If you try to use the new version of Stack, you get an error message saying that the default value std::deque is not compatible with the template template parameter CONT. The problem is that a template template argument must be a template with parameters that exactly match the parameters of the template template parameter it substitutes. Default template arguments of template template arguments are not considered, so that a match cannot be achieved by leaving out arguments that have default values.
The problem in this example is that the std::deque template of the standard library has more than one parameter: The second parameter (which describes a so-called allocator) has a default value, but this is not considered when matching std::deque to the CONT parameter.
There is a workaround, however. We can rewrite the class declaration so that the CONT parameter expects containers with two template parameters:


Again, you can omit ALLOC because it is not used.
The final version of our Stack template (including member templates for assignments of stacks of different element types) now looks as follows:


The following program uses all features of this final version:



Note that template template parameters are one of the most recent features required for compilers to conform to the standard. Thus, this program is a good evaluation of the conformity of your compiler regarding template features.








-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------

-----------------------------------------------------------------