0

I am trying to create a class that can represent different kind of images by using templates. For that, I have created a generic base class (should never be initialized) where the template argument defines how the pixel values should be stored (primarily float or unsigned char).

// Image.h

#pragma once

template<typename T>
class Image
{
public:
    Image () : width (0), height (0), allocatedMemory (0), data (nullptr) {}
    virtual ~Image () { delete [] data; }

protected:
    int width;           // in pixel
    int height;          // in pixel
    int allocatedMemory; // number elements in data
    T* data;             // image data
};

Now, I have another class ColorImage which is derived from Image. It adds another template argument that defines the colour space of the Image:

// ColorImage.h

#pragma once

#include "Image.h"

/**
*   Defines various color spaces.
*   Declared outside of class because of template.
**/
enum class ColorSpace 
{ 
    CS_GRAY = 0, CS_RGB, CS_BGR, CS_HSV, CS_LAB, CS_RGBA, CS_BGRA, CS_ARGB
};

template<typename T, ColorSpace C>
class ColorImage;


// Specialise for T = unsigned char

template<ColorSpace C>
class ColorImage<unsigned char, C> : Image<unsigned char>
{
public:
    ColorImage  () : Image () {}
    ~ColorImage () {}

    template<ColorSpace D>
    void convert (ColorImage<unsigned char, D>* output)
    {
        output->width = width;    // error
        output->height = height;  // error
        output->allocatedMemory = allocatedMemory;  // error

        output->foo = 42;  //error

        // ... output->data handling here ...
    }

private:
    int foo;
};

In the convert() function, I want to convert one colour space to another. For that, I want to copy all data from my original image to output-Image. However, when I call output->width and so on, I get the error C2248: 'Image::width' : cannot access private member declared in class 'Image' .

I also can not access other private members from the other specialisations. output->foo = 42 (see above) throws Cannot access private member declared in class 'ColorImage'. I know I could resolve this by declaring all full specialisations as a friend for the partial specialization, however, that would result in a massive amount of friend-declarations, since I would have to do that for every single full specialisation (for each possible colour space). I also know I could just declare something like a public setFoo (int value), but I don't want to do that either since I don't want to expose the variable to the public. Is there another way of achieving this?

Thanks a lot in advance.

Feelan
  • 1
  • 1

1 Answers1

0

Try deriving ColorImage using public to gain access to it's protected members:

template<ColorSpace C>
class ColorImage<unsigned char, C> : public Image<unsigned char> {
    // ...
};

More about C++ inheritance on this SO post.

Community
  • 1
  • 1
erapert
  • 1,383
  • 11
  • 15
  • 1
    In this case, that's not the problem. The problem is that `TemplateType` is unrelated to `TemplateType` except in text appearance in the code. – Mark B Jan 26 '15 at 19:30