有没有办法在不知道派生类型的情况下将包含派生指针的 std::any 转换为基指针?
Is there any way to cast a std::any containing a derived pointer to a base pointer, without knowing the derived type?
假设我有一个 std::any
对象,它可能包含也可能不包含指向给定基数 class B
的某些派生 class 的指针。我有什么办法可以做到:
- Returns a
B *
,如果 std::any
对象持有可转换为 B *
的东西,或者
- 如果不是则抛出异常?
dynamic_cast
和 std::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);
}
我不想包括一堆样板代码,列出现有的每一种锯,这样我就可以抓一把锯 -- any Saw
-- 在 Factory1
.
中使用
这是无法实现的。只能使用完全放入其中的类型从 std::any
中取出对象。因此,您必须知道类型才能从中获取任何信息。
std::any
似乎不适合您的用例。
添加具有枚举 ToolType 属性的基础 class "Tool" 可以提供帮助。然后使用 ToolType 你可以决定演员表。
我来晚了,刚刚遇到这个问题,我自己正在寻找答案。
这是我最终得出的结论。
我需要在 std::any
中将一个 wxMenuItem* 或指向某种控件的指针(全部派生自 wxControl)传递给我的函数。我知道我是否有一个 wxMenuItem* 或一个基于标志的控件。所以暂时忽略 wxMenuItem* 的。
因为我的代码只需要使用基础 class wxControl 所具有的东西,(我想因为你们的锤子共享一个公共基础 class,所以你只想做基础锤子类型的东西), 我...
static_cast<wxControl*>(myCombo*)
在呼叫点,并且
auto myPtr {std::any_cast<wxControl*>(theAnyField)};
在调用点,瞧。
假设我有一个 std::any
对象,它可能包含也可能不包含指向给定基数 class B
的某些派生 class 的指针。我有什么办法可以做到:
- Returns a
B *
,如果std::any
对象持有可转换为B *
的东西,或者 - 如果不是则抛出异常?
dynamic_cast
和 std::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);
}
我不想包括一堆样板代码,列出现有的每一种锯,这样我就可以抓一把锯 -- any Saw
-- 在 Factory1
.
这是无法实现的。只能使用完全放入其中的类型从 std::any
中取出对象。因此,您必须知道类型才能从中获取任何信息。
std::any
似乎不适合您的用例。
添加具有枚举 ToolType 属性的基础 class "Tool" 可以提供帮助。然后使用 ToolType 你可以决定演员表。
我来晚了,刚刚遇到这个问题,我自己正在寻找答案。
这是我最终得出的结论。
我需要在 std::any
中将一个 wxMenuItem* 或指向某种控件的指针(全部派生自 wxControl)传递给我的函数。我知道我是否有一个 wxMenuItem* 或一个基于标志的控件。所以暂时忽略 wxMenuItem* 的。
因为我的代码只需要使用基础 class wxControl 所具有的东西,(我想因为你们的锤子共享一个公共基础 class,所以你只想做基础锤子类型的东西), 我...
static_cast<wxControl*>(myCombo*)
在呼叫点,并且
auto myPtr {std::any_cast<wxControl*>(theAnyField)};
在调用点,瞧。