0

I read Passing shared_ptr<Derived> as shared_ptr<Base> but that doesn't answer my question.

Suppose we have

class Base
{
};

class Derived : public Base
{
};

I would like to create the following container: std::map<int, std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Base>>>> _channels;

I need to add instances as values with types std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Base>>> and std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Derived>>>.

Unfortunately I'm unable to add instances with Derived type, but with type Base it's fine.

Full code:

#include <iostream>
#include <string>
#include <map>
#include <unordered_map>
#include <memory>
#include <utility>

class Base
{
};

class Derived : public Base
{
};

int main()
{
// works fine
/*
    std::map<int, std::shared_ptr<Base>> _channels2;
    _channels2.emplace(std::pair<int, std::shared_ptr<Derived>>(3, std::make_shared<Derived>()));
    std::cout << "_channels2.size() = " << _channels2.size() << std::endl;
*/

// fails to compile
    std::map<int, std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Base>>>> _channels;
    _channels.emplace(std::pair<int, std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Derived>>>>(2, std::make_shared<std::unordered_map<std::string, std::shared_ptr<Derived>>>()));
    std::cout << "_channels.size() = " << _channels.size() << std::endl;

    return 0;
}

I'm using C++14.

  1. Am I understand well so the reason behind it fails to compile is because std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Derived>>> is not a subtype of std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Base>>>? So polymorphism isn't available in this case.

  2. Is there a workaround you can advise?

Thank you.

cigien
  • 57,834
  • 11
  • 73
  • 112
user2148758
  • 335
  • 1
  • 2
  • 10
  • take two buses: one with only fathers in it, the second one with only their child. Does the first bus need to be the father of the second bus? – OznOg Mar 21 '21 at 16:48
  • Well, yes, my main question was if a language feature exists like wildcard extends parameter in Java. – user2148758 Mar 21 '21 at 19:44

1 Answers1

1

You could try something considering this works:

std::map<std::string, std::shared_ptr<Derived>> derived_map;
std::map<std::string, std::shared_ptr<Base>> base_map(derived_map.begin(), derived_map.end());

thus you can write:

std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Derived>>> derived_map;
auto base_map = std::make_shared<std::unordered_map<std::string, std::shared_ptr<Base>>>(derived_map->begin(), derived_map->end());

an so on... the drawback is that only base and derived are "shared", the maps are duplicated.

OznOg
  • 4,440
  • 2
  • 26
  • 35
  • Thanks for your answer, unfortunately iterating is rarely suits my classes. – user2148758 Mar 21 '21 at 19:48
  • there is no real iteration, I said so on because you used quite complicated structures, so you need to buid them up piece after piece – OznOg Mar 21 '21 at 19:54