8

假设我有一个std::any对象,它可能包含也可能不包含指向给定基类的某个派生类的指针B。有什么办法可以做到:

  1. B *如果std::any对象包含可转换为 的东西,则返回 a B *,或
  2. 如果没有抛出异常?

似乎每个dynamic_caststd::any_cast提供了该功能的一半,但我看不出有任何将两者结合在一起的方法。

我知道我可以通过各种方式完成这项工作,包括显式枚举可转换为的每种类型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);
}

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.

4

3 回答 3

3

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.

于 2019-11-05T19:36:44.767 回答
2

I'm late to the party, just just came across this question looking for an answer myself.

Here's what I eventually worked out.

I needed to pass either a wxMenuItem*, or a pointer to some sort of control (all are derived from wxControl) to my function in an std::any. I know if I have a wxMenuItem* or a control based on flags. So ignore wxMenuItem* 's for now.

As my code only has to work with what a base class wxControl has, (and I imagine since your hammers share a common base class, you only want to do base hammer type stuff), I...

static_cast<wxControl*>(myCombo*)

at the calling point, and

auto myPtr {std::any_cast<wxControl*>(theAnyField)};

at the called point, and voila.

于 2020-10-10T04:39:04.027 回答
0

Adding a base class "Tool" that has an enum ToolType attribute can help out. Then using the ToolType you can decide on the cast.

于 2019-11-26T22:07:18.457 回答