   pointers to templates
  Hi!I was wondering if there's a way to have a pointer to a templated class without specifying the templates, i.e.template <class T>class Image {...}void doSomething(Image* img) {    img->func();}
  Not exactly, but you can do this:template <class T>class Image {...}template <class T>void doSomething(Image<T>* img) {    img->func();}// Or if you prefer:template <class T>void doSomething(T* img) {    img->func();}and then you don't need to specify the template argument when you call doSomething. This is legal:Image<MyClass> im;doSomething(im); // Note, you don't need doSomething<MyClass>;  okay, I've tried it, but it seems to break when linking. More info:image.htemplate <class T = RGBColor, int N = 3, int TexFormat = GL_RGB>class Image {public:Image(int width = 256, int height = 256, T& clearColor = GetBlack<T>());~Image();void Clear(T& c = (T)0);void SetPixel(int i, int j, T& c, int srcMode = BLEND_ONE, int dstMode = BLEND_ZERO);inline void SetPixel(Point2D& p, T& c, int srcMode = BLEND_ONE, int dstMode = BLEND_ZERO) { SetPixel(p.y(), p.x(), c, srcMode, dstMode); }inline void SetPixelXY(int x, int y, T& c, int srcMode = BLEND_ONE, int dstMode = BLEND_ZERO) { SetPixel(y, x, c, srcMode, dstMode); }#define OUTSIDE_RETURN(i, j) if(((i)<0) || ((i)>=m_height) || ((j)<0) || ((j)>=m_width)) return (T)0;#pragma warning(disable : 4172)inline T& GetPixel(int i, int j) { OUTSIDE_RETURN(i, j); return m_data[j]; }inline T& GetPixel(Point2D& p) { OUTSIDE_RETURN(p.y(), p.x()); return m_data[p.y()][p.x()]; }inline T& GetPixelXY(int x, int y) { OUTSIDE_RETURN(y, x); return m_data[y][x]; }inline int Height() { return m_height; }inline int Width() { return m_width; }inline int GetTexID() { return m_texID; }void Bind();private:int m_width, m_height;int m_width10, m_height10;static int m_numTextures;int m_texID;T** m_data;BYTE* m_rawData;};typedef Image<RGBColor, 3, GL_RGB> Image2D;typedef Image<BYTE, 1, GL_LUMINANCE> Image2D_grayscale;image.cpptemplate <class T /*= RGBColor*/, int N /*= 3*/, int TexFormat /*= GL_RGB*/>Image<T, N, TexFormat>::Image(int width /*= 256*/, int height /*= 256*/, T& clearColor /*= (T)0*/) :m_width(width), m_height(height),m_width10(10*width), m_height10(10*height),m_texID(m_numTextures) {++m_numTextures;int index = 0;m_rawData = new BYTE[width*height*N];m_data = new RGBColor*[height];for(int i=0; i<height; ++i) m_data = new T[width];for(int i=0; i<height; ++i)for(int j=0; j<width; ++j) {m_data[j] = clearColor;for(int ni=0; ni<N; ++ni) m_rawData[index+ni] = (BYTE)clearColor[ni];index+=N;}}template <class T /*= RGBColor*/, int N /*= 3*/, int TexFormat /*= GL_RGB*/>Image<T, N, TexFormat>::~Image() {for(int i=0; i<m_height; ++i) delete[] m_data;delete[] m_data;delete[] m_rawData;}template <class T /*= RGBColor*/, int N /*= 3*/, int TexFormat /*= GL_RGB*/>void Image<T, N, TexFormat>::Clear(T& c /*= (T)0*/) {int index = 0;for(int i=0; i<m_height; ++i)for(int j=0; j<m_width; ++j) {m_data[j] = c;for(int ni=0; ni<N; ++ni) m_rawData[index+ni] = (BYTE)c[ni];index+=N;}}template <class T /*= RGBColor*/, int N /*= 3*/, int TexFormat /*= GL_RGB*/>void Image<T, N, TexFormat>::SetPixel(int i, int j, T& c, int srcMode /*= BLEND_ONE*/, int dstMode /*= BLEND_ZERO*/) {if((i<0) || (i>=m_height) || (j<0) || (j>=m_width)) return;T src;T dst;double att = 0.0;src = c;dst = GetPixel(i, j);switch(srcMode) {case BLEND_ZERO:src.Attenuate(0.0, 0.0, 0.0, 0.0); break;case BLEND_ONE:src.Attenuate(1.0, 1.0, 1.0, 1.0); break;case BLEND_SRC_ALPHA:src.Attenuate(c.a(), c.a(), c.a(), c.a()); break;case BLEND_ONE_MINUS_SRC_ALPHA:att = 1.0 - c.a();src.Attenuate(att, att, att, att); break;case BLEND_DST_ALPHA:src.Attenuate(dst.a(), dst.a(), dst.a(), dst.a()); break;case BLEND_ONE_MINUS_DST_ALPHA:att = 1.0 - dst.a();src.Attenuate(att, att, att, att); break;/********* source only *********/case BLEND_DST_COLOR:src.Attenuate(dst.r(), dst.g(), dst.b(), dst.a()); break;case BLEND_ONE_MINUS_DST_COLOR:src.Attenuate(1.0 - dst.r(), 1.0 - dst.g(), 1.0 - dst.b(), 1.0 - dst.a()); break;case BLEND_SRC_ALPHA_SATURATE:att = min(c.a(), 1.0 - dst.a());src.Attenuate(att, att, att, 1.0); break;}switch(dstMode) {case BLEND_ZERO:dst.Attenuate(0.0, 0.0, 0.0, 0.0); break;case BLEND_ONE:dst.Attenuate(1.0, 1.0, 1.0, 1.0); break;case BLEND_SRC_ALPHA:dst.Attenuate(c.a(), c.a(), c.a(), c.a()); break;case BLEND_ONE_MINUS_SRC_ALPHA:att = 1.0 - c.a();dst.Attenuate(att, att, att, att); break;case BLEND_DST_ALPHA:dst.Attenuate(dst.a(), dst.a(), dst.a(), dst.a()); break;case BLEND_ONE_MINUS_DST_ALPHA:att = 1.0 - dst.a();dst.Attenuate(att, att, att, att); break;/********* destination only *********/case BLEND_SRC_COLOR:dst.Attenuate(c.r(), c.g(), c.b(), c.a()); break;case BLEND_ONE_MINUS_SRC_COLOR:dst.Attenuate(1.0 - c.r(), 1.0 - c.g(), 1.0 - c.b(), 1.0 - c.a()); break;}T final(src+dst);m_data[j] = final;int index = (i*m_width + j)*N;for(int ni=0; ni<N; ++ni) m_rawData[index+ni] = (BYTE)final[ni];}template <class T /*= RGBColor*/, int N /*= 3*/, int TexFormat /*= GL_RGB*/>void Image<T, N, TexFormat>::Bind() {glBindTexture(GL_TEXTURE_2D, m_texID);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);glTexImage2D(GL_TEXTURE_2D, 0, N, m_width, m_height, 0, TexFormat, GL_UNSIGNED_BYTE, m_rawData);}template <class T /*= RGBColor*/, int N /*= 3*/, int TexFormat /*= GL_RGB*/>int Image<T, N, TexFormat>::m_numTextures = 0;It's for use in things like:#define SWAP(a, b) { int *tmp; tmp = (a); (a) = (b); (b) = tmp; }class Line2D : public Shape {public:Line2D(int sx, int sy, int ex, int ey) :m_sx(sx), m_sy(sy), m_ex(ex), m_ey(ey) {}Line2D(Point2D start, Point2D end) :m_sx(start.x()), m_sy(start.y()), m_ex(end.x()), m_ey(end.y()) {}template <class T>void Draw(T *img, RGBColor& c = WHITE, int srcMode = BLEND_ONE, int dstMode = BLEND_ZERO);private:int m_sx, m_sy, m_ex, m_ey;};template <class T>void Geometry::Line2D::Draw(T *img, RGBColor& c /*= WHITE*/, int srcMode /*= BLEND_ONE*/, int dstMode /*= BLEND_ZERO*/) {int *x0 = &m_sx, *y0 = &m_sy, *x1 = &m_ex, *y1 = &m_ey;bool steep = abs(*y1 - *y0) > abs(*x1 - *x0);if(steep) {SWAP(x0, y0);SWAP(x1, y1);}if(*x0 > *x1) {SWAP(x0, x1);SWAP(y0, y1);}int deltax = *x1 - *x0;int deltay = abs(*y1 - *y0);int error = -(deltax + 1)/2;int ystep;int y = *y0;if(*y0 < *y1) ystep = 1; else ystep = -1;for(int x = *x0; x <= *x1; ++x) {if(steep)img->SetPixel(x, y, c, srcMode, dstMode);elseimg->SetPixel(y, x, c, srcMode, dstMode);error += deltay;if(error >= 0) {y += ystep;error -= deltax;}}}Right now, though, it doesn't link.I fixed the missing Image<RGBColor, 3, GL_RGB>::Image(...) and Image<RGBColor, 3, GL_RGB>::~Image() and the successive missing Image<RGBColor, 3, GL_RGB> methods by redefining everything with template<> Image<RGBColor, 3, GL_RGB>::method (totally defeats the purpose), but I don't feel like rewriting each Figure::Draw to work on different Image templates.Does anyone have any idea what I'm doing wrong?   ;Solution.   