I need to be able to store any specialization of a template in a variable eg:
template<T>
class Grid {
int GetRows();
int GetTypeOfColumn(int col);
//...etc...
}
//EDIT:
Grid<int>::GetTypeofColumn(int col) {
return col == 0 ? STRING_COL_TYPE : INT_COL_TYPE;
}
Grid<string>::GetTypeofColumn(int col) {
return STRING_COL_TYPE;
}
//End EDIT
class Foo {
Grid<int>* aBunchOfNumbers;
Grid<string>* aBunchOfStrings;
//...etc...
}
//in some function, say `wants` is an enum, and foo is gotten from somewhere:
Foo* foo;
switch wants {
case NUMBERS:
std::cout << "Rows: " << foo->aBunchOfNumbers->GetRows() << std::endl;
std::cout << "Col0 is: " << foo->aBunchOfNumbers->GetTypeofColumn(0) << std::endl;
//...etc...
break;
case STRINGS:
std::cout << "Rows: " << foo->aBunchOfNumbers->GetRows() << std::endl;
std::cout << "Col0 is: " << foo->aBunchOfNumbers->GetTypeofColumn(0) << std::endl;
//...etc...
break;
}
it would be easier to do:
Foo* foo;
Grid* grid;
switch wants {
case NUMBERS:
grid = foo->aBunchOfNumbers;
break;
case STRINGS:
grid = foo->aBunchOfStrings;
break;
}
std::cout << "Rows: " << grid->GetRows() << std::endl;
std::cout << "Col0 is: " << grid->GetTypeofColumn(0) << std::endl;
//...etc...
In the same way if I used subclasses like this: http://ideone.com/MPKy1w
I'm aware that class templates are almost basically macros and how the compiler actual compiles them, but is there no way to refer to the specializations generically and save repetition?
(I'm using pointers deliberately here, I have no choice in my actual code, which I can not copy here)
Create class with desired methods ("interface"). It is possible to do so because your methods do not depend on template argument T
:
class GridOperations {
virtual int GetRows() = 0;
virtual int getTypeOfColumn(int col) = 0;
virtual ~GridOperations() {}
};
Now inherit Grid from above class:
template<T>
class Grid : public GridOperations {
int GetRows() { /* impl */ }
int GetTypeOfColumn(int col) { /* impl */ }
};
Now you may cast both Grid<int>*
and Grid<string>*
to GridOperations*
:
Foo* foo;
GridOperations* ops;
switch wants {
case NUMBERS:
ops = foo->aBunchOfNumbers;
break;
case STRINGS:
ops = foo->aBunchOfStrings;
break;
}
std::cout << "Rows: " << ops->GetRows() << std::endl;
std::cout << "Col0 is: " << ops->GetTypeofColumn(0) << std::endl;
Bonus: and you may even use std::map<WantEnumType, GridOperations*>
to avoid nasty switch block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With