bergercookie
bergercookie

Reputation: 2760

Associative container to handle one element polymorphically

Suppose I have the following setup:

#include <iostream>
#include <map>

using namespace std;

class A
{
public:
    A() { val1 = 1;}
    ~A() { }

private:
    int val1;
};

class B
{
public:
    B() { val2 = 1;}
    ~B() { }
    int getVal() {return val2;}

private:
    int val2;
};

class C : public A, public B
{

    int val3;
};

void fun(std::pair<int, B>& p) {
    cout << "B val: " << p.second.getVal() << endl;
}

void fun2(B& b) {
    cout << "B val: " << b.getVal() << endl;
}

int main(int argc, const char *argv[])
{

    map<int, C> m;
    m.insert(make_pair(1, C()));
    m.insert(make_pair(2, C()));

    //fun(*(m.begin())); // <---- Compilation error
    fun2(m.at(1)); // Works correctly

    return 0;
}

Code compiles successfully and works as expected when I make the call to fun2. However if I uncomment the line fun(*(m.begin()) I get the following compilation error:

a.cpp: In function ‘int main(int, const char**)’:
a.cpp:48:18: error: invalid initialization of reference of type ‘std::pair<int, B>&’ from expression of type ‘std::pair<const int, C>’
  fun(*(m.begin()));
                  ^
a.cpp:33:6: error: in passing argument 1 of ‘void fun(std::pair<int, B>&)’
 void fun(std::pair<int, B>& p) {

Is there any way to make the compiler handle the second element of std::pair polymorphically?

P.S. Sorry if the title is misleading in any way. Couldn't find a better way of expressing this.

Upvotes: 0

Views: 63

Answers (1)

user2100815
user2100815

Reputation:

This:

 *(m.begin())

evaluates to a nameless temporary object. To bind this to a reference, the reference must be const, so:

 void fun(const std::pair<int, B>& p) {

and for that function to call getVal(), that must be const too:

 int getVal() const {return val2;}

Upvotes: 1

Related Questions