有没有办法向这个向量添加元素?
Is there a way to add elements to this vector?
我有一个 class Column.h
、一个模板 ColumnImpl.h
和一个 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;
};
我现在想做的是,使用方法 addElem
向 ColumnImpl.h
中的模板向量添加元素,然后在 addElemToCol
.[=30= 中调用它]
为此我已经尝试过(在 addElemToCol
内):
if (this->colIsPresent(col_name)) {
const auto & it = _columns.find(col_name);
it->second.get().
}
但在这里我意识到我没有 addElem
方法...我该如何解决这个问题?
编辑 1:
这就是我检查类型并将其添加到向量中的方式:
int data;
data_stream >> data;
if (!data_stream.fail()) {
if (target_database.tabIsPresent(tab_name)) {
target_database.addElemToColOfTab(tab_name, col_name, data);
}
这是一个Database
方法:
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);
}
这是一个Tab
方法:
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
}
}
}
并且每个 class IntColumn
、FloatColumn
都有自己的实现:
void addElem(const int& elem_to_add) { _data.push_back(elem_to_add); } // this is for IntColumn
您收到此错误是因为 所有 开关块需要编译,即使只使用一个开关块也是如此。 p_int->addElem(data_to_add);
只能在 data_to_add
的类型匹配相应的 ColumnImpl
模板类型时才能编译,并且只有 一个 的情况是这样。
因为您知道 S
是什么,所以您实际上不需要经历任何类型检查环节;您可以完全消除 switch
,只查找 ColumnImpl<S>
。我们还可以让函数 return 一个布尔值,指示添加元素是否成功。
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;
}
我有一个 class Column.h
、一个模板 ColumnImpl.h
和一个 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;
};
我现在想做的是,使用方法 addElem
向 ColumnImpl.h
中的模板向量添加元素,然后在 addElemToCol
.[=30= 中调用它]
为此我已经尝试过(在 addElemToCol
内):
if (this->colIsPresent(col_name)) {
const auto & it = _columns.find(col_name);
it->second.get().
}
但在这里我意识到我没有 addElem
方法...我该如何解决这个问题?
编辑 1:
这就是我检查类型并将其添加到向量中的方式:
int data;
data_stream >> data;
if (!data_stream.fail()) {
if (target_database.tabIsPresent(tab_name)) {
target_database.addElemToColOfTab(tab_name, col_name, data);
}
这是一个Database
方法:
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);
}
这是一个Tab
方法:
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
}
}
}
并且每个 class IntColumn
、FloatColumn
都有自己的实现:
void addElem(const int& elem_to_add) { _data.push_back(elem_to_add); } // this is for IntColumn
您收到此错误是因为 所有 开关块需要编译,即使只使用一个开关块也是如此。 p_int->addElem(data_to_add);
只能在 data_to_add
的类型匹配相应的 ColumnImpl
模板类型时才能编译,并且只有 一个 的情况是这样。
因为您知道 S
是什么,所以您实际上不需要经历任何类型检查环节;您可以完全消除 switch
,只查找 ColumnImpl<S>
。我们还可以让函数 return 一个布尔值,指示添加元素是否成功。
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;
}