Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to cast a std::any containing a derived pointer to a base pointer, without knowing the derived type?

Tags:

c++

stdany

Let's say I have a std::any object which may or may not contain a pointer to some derived class of a given base class B. Is there any way I can do something that:

  1. Returns a B *, if the std::any object holds something convertible to B *, or
  2. Throws an exception if not?

It seems like dynamic_cast and std::any_cast each provide one half of this functionality, but I don't see any way of putting the two together.

I'm aware that I can make this work in various ways that involve explicitly enumerating every type convertible to B *, but that's the mother of all DRY violations.


Sample use case:

std::vector<std::any> setupTools(const std::string & confFile)
{
  std::vector<std::any> myTools;

  auto conf = parse(confFile);

  for(std::string & wrenchInfo : conf["Wrenches"])
  {
    Wrench::setup(myTools, wrenchInfo);
  }    

  for(std::string & hammerInfo : conf["Hammers"])
  {
    Hammer::setup(myTools, hammerInfo);
  }

   // 25 more kinds of tools
}

Factory1::init(const std::vector<std::any> & tools)
{
  m_wrench = any_get<Wrench *>(tools);
  m_hammer = any_get<Hammer *>(tools);
  m_saw = any_get<Saw *>(tools);
}

Factory2::init(const std::vector<std::any> & tools)
{
  m_wrench = any_get<TorqueWrench *>(tools);
}

Factory3::init(const std::vector<std::any> & tools)
{
  m_saw = any_get<CordlessReciprocatingSaw *>(tools);
}

I don't want to include a bunch of boilerplate code listing every single kind of saw in existence just so I can grab a saw -- any Saw -- to use in Factory1.

like image 795
Daniel McLaury Avatar asked Nov 05 '19 19:11

Daniel McLaury


People also ask

Can you convert a pointer from a derived class to its base class?

[19.4] Is it OK to convert a pointer from a derived class to its base class? Yes.

Can you cast a base class to a derived class in C++?

C++ Explicit type conversions Base to derived conversion Likewise, a reference to base class can be converted to a reference to derived class using static_cast . If the source type is polymorphic, dynamic_cast can be used to perform a base to derived conversion.

Can a derived class have pointer objects?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.

Can a base class pointer call methods in the derived class?

Is it possible for base class pointers to call methods declared in the derived class only? No, you can only call methods that are part of the class.


1 Answers

This is unachievable. It is only possible to get an object out from std::any using exactly the type that was put inside. Thus, you must know the type to get anything out of it.

It seems that std::any does not fit your use case.

like image 158
eerorika Avatar answered Oct 03 '22 04:10

eerorika