norski_lab
norski_lab

Reputation: 41

Put a datatype as a string into a template argument - C++

I am writing a program that needs to create certain images with different data types. I am using templates since that is the best method. The program reads in an image file with a magic number at the top(P11,P12,P13,P14) below the magic number are three numbers that specify the width, height, and max value. The rest of the file contains the (width*height) amount of numbers and all of those numbers have to be within 0 and the max value.

Here is an example file:

P11
3 4
512

78 90 102
23 489 209
123 423 1
100 231 134

Note that this is only an example and our files are usually thousands of lines long.

For this program we have to check the magic number and the max value in the header. These values dictate what datatype we use and thus we would just plug that into the template. The problem is that my template cannot take a string as a parameter like so:

string dataType = inFile.getType(vector of numbers);
Image<dataType> img1 (Rows,columns,numbers);

I have 10 cases that I need to account for and each case would look like this-> If the magic number is P11 and the max value is less than 256 then the data type is a "unsigned char". If the magic number is P11 and the max value is greater than 256 but less than 65536 than the datatype for our image would be an "unsigned short". I go through this depending on what the magic number and the max value is. So for our image above we would have a datatype of "unsigned short".

What I have so far is a method that accounts for each case and returns a string telling me what the datatype should be regarding the magic number and the max value. The only thing is that my template cannot take a string to make it the correct data type.

My only solution I have come up with is to do if-else statements in the main. It is very messy because if i have more than one image the if-else statements double. Here is an example

if(dataType == "unsigned char"){
   Image<unsigned char> img1 (rows, columns, numbers);

}
else if(dataType == "unsigned short"){
   Image<unsigned short> img1 (rows, columns, numbers);   

}

and so on for the other 8 cases...Is there anyway I can return a datatype from a method and directly put that into a template argument? I can submit some code but not a lot because I don't want other students looking for an easy way out. Let me know what would be the most beneficial to look at and I can change it around. Thank you for the help in advanced.

Upvotes: 0

Views: 95

Answers (1)

Glenn Teitelbaum
Glenn Teitelbaum

Reputation: 10333

Your problem isn't actually string templates, if you had ints you'd have the same issue This is the basic dilema of translating realtime values to compile time templates datatype is determined at runtime - so the compiler can't know what type it will be when run Even if you use ifs - you can't decide the type of img1 at runtime and then use it below, you would have to either call all your methods in the loop, or as commented have a common base class

to illustrate using the base class and static factory mentioned above:

template <typename T> class img; // forward declare
class img_base
{
public:
    virtual void process();
    static img_base * get_processor(int type)
    {
         switch (type)
         {
            case 0:
                return new img<unsigned char>;
            case 1:
                return new img<unsigned short>;
         .....

}

template <typename T>
class img : public img_base
{
public:
    void process(); // do type specific stuff
}

And as commented this takes an int - hopefully this will be enough for you to continue working on this.

Upvotes: 2

Related Questions