I have the following priority_queue with items of type base. The problem is, when I get item from the Queue with top(), then call its f() function via base reference object, it does call the f of base class but not the overriden f. I want child object's f() to be called. Any help? Thanks..
#include <queue>
#include <iostream>
using namespace std;
class base {
public:
int id;
virtual void f() const {
cout << "base f()" << endl;
}
};
class D1: public base {
public:
void f() const {
cout << "D1 f()" << endl;
}
};
class D2: public base {
public:
void f() const {
cout << "D2 f()" << endl;
}
};
bool operator<(const base& b1, const base& b2)
{
return b1.id > b2.id;
}
int main()
{
priority_queue<base, deque<base>, less<deque<base>::value_type> > Q;
D1 d1;
D2 d2;
Q.push(d1);
Q.push(d2);
// this is not something I want
const base& b = Q.top();
b.f(); // base f()
// this works as I want
const base& b2 = d2;
b2.f(); // D1 f()
return 0;
}
Same polymorphic premise as using pointers, but here's a possible alternative using std::reference_wrapper
:
#include <functional>
#include <queue>
#include <iostream>
using namespace std;
class base {
public:
int id;
virtual void f() const {
cout << "base f()" << endl;
}
};
class D1: public base {
public:
void f() const {
cout << "D1 f()" << endl;
}
};
class D2: public base {
public:
void f() const {
cout << "D2 f()" << endl;
}
};
bool operator<(const base& b1, const base& b2)
{
return b1.id > b2.id;
}
int main()
{
priority_queue<std::reference_wrapper<base>, deque<std::reference_wrapper<base>>, less<deque<std::reference_wrapper<base>>::value_type> > Q;
D1 d1;
D2 d2;
Q.push(d1);
Q.push(d2);
// this now works as you want?
const auto& b = Q.top();
b.get().f(); // D1 f()
// this works as I want
const auto& b2 = d2;
b2.f(); // D2 f()
return 0;
}