Professional C__ - Marc Gregoire [350]
char* getElementAt(size_t x, size_t y) const;
size_t getHeight() const { return HEIGHT; }
size_t getWidth() const { return WIDTH; }
protected:
void copyFrom(const Grid char* mCells[WIDTH][HEIGHT]; }; Code snippet from GridPartialString\GridString.h In this case, you are not specializing all the template parameters. Therefore, your template line looks like this: template class Grid Note that the template has only two parameters: WIDTH and HEIGHT. However, you’re writing a Grid class for three arguments: T, WIDTH, and HEIGHT. Thus, your template parameter list contains two parameters, and the explicit Grid Grid Grid Grid<2, 3> test; // DOES NOT COMPILE! No type specified. Code snippet from GridPartialString\GridTestString.cpp Yes, the syntax is confusing. And it gets worse. In partial specializations, unlike in full specializations, you include the template line in front of every method definition: template Grid { for (size_t i = 0; i < WIDTH; i++) { for (size_t j = 0; j < HEIGHT; j++) { mCells[i][j] = nullptr; // Initialize each element to nullptr. } } } Code snippet from GridPartialString\GridString.h You need this template line with two parameters to show that this method is parameterized on those two parameters. Note that wherever you refer to the full class name, you must use Grid You can find the rest of the method definitions in the downloadable source code archive for this book on www.wrox.com. Another Form of Partial Specialization The previous example does not show the true power of partial specialization. You can write specialized implementations for a subset of possible types without specializing individual types. For example, you can write a specialization of the Grid class for all pointer types. This specialization might perform deep copies of objects to which pointers point instead of storing shallow copies of the pointers in the grid. Here is the class definition, assuming that you’re specializing the initial version of the Grid with only one parameter: #include "Grid.h" 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, T* inElem); 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 T*** mCells; size_t mWidth, mHeight; }; Code snippet from GridPartialPtr\GridPtr.h As usual, these two lines are the crux of the matter: template class Grid The syntax says that this class is a specialization of the Grid template for all pointer types. At least that’s what it’s telling the compiler. What it’s telling you and me is that the C++ standards committee should have come up with a better syntax. Unless you’ve been working with it for a long time, it’s quite jarring. You are providing the implementation only in cases where T is a pointer type. Note that if you instantiate a grid like this: Grid Grid Grid int x = 3, y = 4; psGrid.setElementAt(0, 0, &x); psGrid.setElementAt(0, 1, &y); psGrid.setElementAt(1, 0, &y);