Reputation: 105
I have a class Column.h
, a template ColumnImpl.h
and a Tab.h
class Column {
public:
Column() {}
virtual ~Column() {};
virtual string getType() = 0;
};
template <typename T> class ColumnImpl : public Column {
public:
ColumnImpl() : Column() {}
void addElem(const T& elem_to_add);
protected:
vector<T> _data;
};
class Tab {
public:
Tab();
~Tab() {};
template <typename S> void addElemToCol(const string & col_name, const S & data_to_add);
private:
map<string, shared_ptr<Column>> _columns;
};
What I would like to do now, is adding elements to the template vector inside ColumnImpl.h
using the method addElem
, and then recalling it inside addElemToCol
.
To do that I've tried (inside addElemToCol
):
if (this->colIsPresent(col_name)) {
const auto & it = _columns.find(col_name);
it->second.get().
}
But here I realized I don't have the addElem
method... How can I solve this issue?
EDIT 1:
This is how I'm checking the type and adding it into the vector:
int data;
data_stream >> data;
if (!data_stream.fail()) {
if (target_database.tabIsPresent(tab_name)) {
target_database.addElemToColOfTab(tab_name, col_name, data);
}
This is a Database
method:
template <typename D> void addElemToColOfTab(const string & tab_name, const string & col_name, const D& data_to_add) {
const auto & it_target_tab = _tables.find(tab_name);
it_target_tab->second.addElemToCol(col_name, data_to_add);
}
This is a Tab
method:
template <typename S> void addElemToCol(const string & col_name, const S & data_to_add) {
if (this->colIsPresent(col_name)) {
const auto & it = _columns.find(col_name);
switch (Type2Int(it->second->getType())) {
case OptionInt: {
ColumnImpl<int>* p_int = dynamic_cast<ColumnImpl<int> *>(it->second.get());
if (p_int != nullptr) {
p_int->addElem(data_to_add);
}
break;
}
case OptionFloat: {...}
// [...] All the other Columns
}
}
}
And every class IntColumn
, FloatColumn
has its own implementation:
void addElem(const int& elem_to_add) { _data.push_back(elem_to_add); } // this is for IntColumn
Upvotes: 0
Views: 74
Reputation: 169018
You are getting this error because all of the switch blocks need to compile even if only one is taken. p_int->addElem(data_to_add);
can only compile when the type of data_to_add
matches the corresponding ColumnImpl
template type, and that's only true in one of the cases.
Since you know what S
is, you don't actually need to go through any of the type-checking hoops; you can eliminate the switch
altogether and just look for ColumnImpl<S>
. We can also have the function return a bool indicating whether adding the element was successful.
template <typename S>
bool addElemToCol(const string & col_name, const S & data_to_add) {
const auto & it = _columns.find(col_name);
if (it != _columns.end()) {
auto ci = dynamic_cast<ColumnImpl<S> *>(it->second.get());
if (ci != nullptr) {
ci->addElem(data_to_add);
return true;
}
}
return false;
}
Upvotes: 1