John Bardeen
John Bardeen

Reputation: 105

Is there a way to add elements to this vector?

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

Answers (1)

cdhowie
cdhowie

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

Related Questions