I would like to have a function that accepts a std::map containing a (pointer to a) base class, but I can't get it to work. Here is my minimal and simplified example:
struct Entity {
  int i;
  Entity(const int i_) : i(i_) {}
  virtual ~Entity() {}
};
struct A : public Entity {
  bool a;
  A(const int i_, const bool a_) : Entity(i_), a(a_) {}
};
void efunc(const std::map<int, std::shared_ptr<Entity>>& m) {
  for (auto& it : m) {
    std::cout << it.second->i << std::endl;
  }
}
int main() {
  std::map<int, std::shared_ptr<A>> aMap;
  std::shared_ptr<A> myA = std::make_shared<A>(1, true);
  aMap.insert({myA->i, myA});
  // efunc(aMap);  // DOES NOT WORK
}
Obviously simply passing the map this way is not allowed, but how can I make it work?
As a bonus, how would I detect the type in the map so that I can execute code specific to that subclass?
Thank you in advance!
Update: Using templates seems to do the trick, this is what I'm using right now:
template <class T>
void tfunc(const std::map<int, std::shared_ptr<T>>& m) {
  for (auto& it : m) {
    std::cout << it.second->i << std::endl;
  }
}
It does feel a bit strange, since I loose IntelliSense and I don't understand why the compiler is not giving me an error. I feel like concepts might help (e.g. to make sure T inherits Entity), but this is beyond what I need right now.
Thank you again for all the responses!
Update 2: Alright, here it is using concepts to ensure that the template containst the member i:
template <class T>
concept hasI = requires(T a) { a.i; };
template <class T>
concept inheritsEntity = std::derived_from<T, Entity>;
template <hasI T>  
/// alternative: template<inheritsEntity T>
void tfunc(const std::map<int, std::shared_ptr<T>>& m) {
  for (auto& it : m) {
    std::cout << it.second->i << std::endl;
  }
}
 
     
     
    