Professional C__ - Marc Gregoire [345]
// Omitted for brevity
};
Code snippet from FriendFunctionTemplates\Grid.h
This friend declaration is tricky: You’re saying that, for an instance of the template with type T, the T instantiation of operator<< is a friend. In other words, there is a one-to-one mapping of friends between the class instantiations and the function instantiations. Note particularly the explicit template specification SUMMARY The next chapter continues the discussion on templates with some more advanced features such as variadic templates and metaprogramming. Chapter 20 Advanced Templates What the details are of the different kinds of template parameters How to use partial specialization How to write recursive templates How to write type-safe variable arguments functions using variadic templates What metaprogramming is and how to use it The previous chapter covered the most widely used features of class and function templates. If you are interested in only a basic knowledge of templates so that you can better understand how the STL works, or perhaps write your own simple classes, you can skip this chapter on advanced templates. However, if templates interest you and you want to uncover their full power, continue reading this chapter to learn about some of the more obscure, but fascinating, details. MORE ABOUT TEMPLATE PARAMETERS More about Template Type Parameters Type parameters to templates are the main purpose of templates. You can declare as many type parameters as you want. For example, you could add to the grid template a second type parameter specifying another templatized class container on which to build the grid. The standard template library defines several templatized container classes, including vector and deque, which are introduced in Chapter 12. In your original grid class you might want to have an array of vectors or an array of deques instead of just an array of arrays. With another template type parameter, you can allow the user to specify whether she wants the underlying container to be a vector or a deque. Here is the class definition with the additional template parameter: template class Grid { public: Grid(size_t inWidth = kDefaultWidth, size_t inHeight = kDefaultHeight); Grid(const Grid virtual ~Grid(); Grid void setElementAt(size_t x, size_t y, const T& inElem); T& getElementAt(size_t x, size_t y); const T& getElementAt(size_t x, size_t y) const; size_t getHeight() const { return mHeight; } size_t getWidth() const { return mWidth; } static const size_t kDefaultWidth = 10; static const size_t kDefaultHeight = 10; protected: void copyFrom(const Grid Container* mCells; size_t mWidth, mHeight; }; Code snippet from GridTemplateContainer\Grid.h This template
This chapter started a discussion on using templates for generic programming. You saw the syntax on how to write templates and examples where templates are really useful. It explained how to write class templates, how to organize your code in different files, how to use template parameters, and how to templatize methods of a class. It further discussed how to use template class specialization to write special implementations of a template where the template types are replaced with specific types. The chapter finished with an explanation of function templates.
WHAT’S IN THIS CHAPTER?
There are actually three kinds of template parameters: type, non-type, and template template (no, you’re not seeing double: that really is the name). You’ve seen examples of type and non-type parameters in the previous chapter, but not template template parameters yet. There are also some tricky aspects to both type and non-type parameters that are not covered in the previous chapter.