Есть ли способ привести std :: any, содержащий производный указатель на базовый указатель, не зная производного типа? - PullRequest
8 голосов
/ 05 ноября 2019

Допустим, у меня есть std::any объект, который может содержать или не содержать указатель на некоторый производный класс данного базового класса B. Можно ли как-нибудь сделать что-то, что:

  1. Возвращает B *, если объект std::any содержит что-то конвертируемое в B *, или
  2. Бросает исключение, еслине так?

Кажется, что dynamic_cast и std::any_cast каждый обеспечивает половину этой функциональности, но я не вижу никакого способа соединить их вместе.

IЯ знаю, что могу выполнить эту работу различными способами, включая явное перечисление каждого типа, преобразуемого в B *, но это является причиной всех нарушений DRY.


Пример использования:

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);
}

Я не хочу включать кучу шаблонного кода, в котором перечислены все существующие типы пил, чтобы я мог взять пилу - любую Saw - для использования в Factory1.

1 Ответ

1 голос
/ 05 ноября 2019

Это недостижимо. Вытащить объект из std::any возможно только с использованием именно того типа, который был помещен внутрь. Таким образом, вы должны знать тип, чтобы извлечь из него что-либо.

Кажется, что std::any не подходит для вашего варианта использования.

...