I have a class template OListType. I want to create an instance of this class that will hold variable input depending on what type of input the user wants to store in the array. I have it set up to have three different data types to be held in the array (char, int, and string), and depending on user input it will create it - no problem yet. Later on in the program to test the class, I get hit with an error every time I try to call one of the class functions, with the error message I receive being "error: 'items' undeclared identifier".
My question is, is it even POSSIBLE to have a class template accept and manipulate various types of data without having to basically write a separate case for every single type of data I want it to use?
Scope (the curly braces were added to illustrate the problem, they do not change your code)
1 2 3 4 5 6 7 8 9
if(num == 1){
OListType<char> *items = new OListType<char>(100);
} //items of char die here.
elseif(num == 2){
OListType<int> *items = new OListType<int>(100);
}//items of int die here
elseif(num == 3){
OListType<string> *items = new OListType<string>(100);
}//items of string (?) die here
The whole point of templates is to seperate implementation from type. I haven't read your code but whether or not this is possible depends entirely on the functionality of your class. If it is not possible however, then a template class is not a suitable design solution.
Thanks for catching the scope thing ne - I was in a meeting when I got an email about your response, and a couple of funny looks when I facepalmed. What I was hoping to do, was declare an OListType pointer globally, without having to assign it to a particular datatype, that way I could do the instantiation using JUST that.
template<class T> void foo(); //sorry for the name
int main(){
cout << "\nWhat type of data would you like the list to hold?: ";
cout << "\n1. Char\n";
cout << "2. Int\n";
cout << "3. Float\n";
cout << "Please make your selection: ";
cin >> num;
switch(num){
case Type_int /*an enum*/: foo<int>(); break;
case Type_char : foo<char>(); break;
case Type_string : foo<std::string>(); break;
default : std::cout << "Invalid selection.\n";
}
}
template<class T>
void foo(){
OListType<T> items(100); //an object, not a pointer
int choice;
cout << cat("menu.txt");
while( cin>>choice )
switch(choice){
//do what you want with your list
}
}
Note: cat is a function that returns a string with the content of the file passed. (you need to implement it)
I tried putting the constructors in a switch statement, but get an error that initialization of 'items' is skipped by 'case' label. Are you suggesting with the code to basically get the data type of the list first and create it, then put everything else nested within that level so that it doesn't go out of scope?
Ok...kinda starting over from scratch here... here is my class - through the constructor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
template <class T>
class OListType {
private:
T *items;
int count;
int maxsize;
public:
OListType<T>::OListType( int size_t) {
maxsize = size_t;
count = 0;
T *items[size_t];
}
What I'm wanting to do is use one variable name (in this case 'items'), and feed it into the constructor. The constructor would then create an object of an array of items of type T. I'm not allowed to create extra functions for this.
Attempt 1: Tried using OListType<T> *items; for a declaration of *items pointing at an OListType<T> object.
Result 1: T isn't declared so it's a no go.
Attempt 2: Switch statement.
Lesson learned: Can't put constructors in switch statements unless they're within brackets - however as soon as the block is done, they go out of scope.
Thoughts: If there was a way to set T to 'int' 'char' or 'string' (the data types I've decided to use), it might work. But is that possible?
Exactly.
With the type you know what function to call. That function is responsible to create the proper list, and to handle the operations on that list.
OListType<T>::OListType( int size_t) {
maxsize = size_t;
count = 0;
T *items[size_t]; //local variable items
} //local variable dies
I'm not allowed to create extra functions for this.
Sorry, but that is an stupid restriction.
cout << "2. Insert an element into the list.\n"; For now, don't think in the list. How could you fulfil this requirement? How could you read the element?