neo neo - 4 days ago 5
C++ Question

vector of Base unique_ptr to derive

I am trying below code to create a vector of Base class and dynamically allocate of derived class.

#include <memory>
#include <vector>
#include <iostream>
#include <algorithm>

class Base {

public:
Base(int value) : item(value) {}
int item;
};

class Derived : public Base {

public:
Derived() : Base(0) {}
};

class Fac {
public:
int count;
std::vector<std::unique_ptr<Base>> m_BaseObj;

void add(int data) {
count++;
m_BaseObj.push_back(std::unique_ptr<Base>(new Derived()));
int index = (m_BaseObj.size() - 1);
std::cout << "Index=" << index << std::endl;
m_BaseObj[index].get()->item = data;
}

void display() {
for (auto &Obj : m_BaseObj) {
std::cout << Obj.get()->item << " ";
}
std::cout << std::endl;
}
void deleteList() {
int it;
std::cout << "Enter item to delete:";
std::cin >> it;
int index = 0;
m_BaseObj.erase(std::remove_if(m_BaseObj.begin(), m_BaseObj.end(),
[it](const std::unique_ptr<Derived> &e) {
return it == e->item;
}),
m_BaseObj.end());
}
};

int main() {
Fac obj;
int ch;
obj.count = 0;
while (1) {
std::cout << "1. Add 2. Remove 3. Display\n";
std::cin >> ch;
switch (ch) {
case 1:
int data;
std::cout << "Data: ";
std::cin >> data;
obj.add(data);
obj.display();
break;
case 2:
obj.deleteList();
obj.display();
break;
case 3:
obj.display();
break;
default:
std::cout << "Invalid choice\n";
exit(0);
}
}
}


Here is the compile error while allocating for derive class. If I create for Derive than the code seems to work correctly.

In file included from /usr/include/c++/4.8/algorithm:62:0,
from vector.cpp:4:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of â_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = __gnu_cxx::__normal_iterator<std::unique_ptr<Base>*, std::vector<std::unique_ptr<Base> > >; _Predicate = Fac::deleteList()::__lambda0]â:
vector.cpp:53:64: required from here
/usr/include/c++/4.8/bits/stl_algo.h:1150:33: error: no match for call to â(Fac::deleteList()::__lambda0) (std::unique_ptr<Base>&)â
if(!bool(__pred(*__first)))
^
vector.cpp:52:48: note: candidate is:
m_BaseObj.begin(), m_BaseObj.end(), [it](const std::unique_ptr<Derived>& e)
^
vector.cpp:52:83: note: Fac::deleteList()::__lambda0
m_BaseObj.begin(), m_BaseObj.end(), [it](const std::unique_ptr<Derived>& e)

Answer

Your predicate to remove_if needs to accept pointer to Base, not Derived. You can do the casting within it.

Compiler error is actually pretty clear.

Comments