Friday, January 17, 2014

template member variable c++

template member variable c++ : templates tutorial
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 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:


No comments:

Post a Comment