Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::动态指针强制转换isn';t正确向下浇铸_C++_Templates_Stl_Casting_Smart Pointers - Fatal编程技术网

C++ std::动态指针强制转换isn';t正确向下浇铸

C++ std::动态指针强制转换isn';t正确向下浇铸,c++,templates,stl,casting,smart-pointers,C++,Templates,Stl,Casting,Smart Pointers,我有一个问题,我将在发布代码后解释: template <class T> std::shared_ptr<T> getWidget(const std::string& id) { auto iter = findObject(id); if (iter != m_widgets.end()) return std::dynamic_pointer_cast<T>(*iter); return nullptr; } const W

我有一个问题,我将在发布代码后解释:

template <class T> 
std::shared_ptr<T>
getWidget(const std::string& id) {
  auto iter = findObject(id);

  if (iter != m_widgets.end()) return std::dynamic_pointer_cast<T>(*iter);

  return nullptr;
}

const Widget::Ptr
getType(const std::string& id) {
  auto iter = findObject(id);

  if (iter != m_widgets.end()) {
    if ((*iter)->getWidgetType() == "Label")
      return std::dynamic_pointer_cast<Label>(*iter);
    else if ((*iter)->getWidgetType() == "Editbox")
      return std::dynamic_pointer_cast<EditBox>(*iter);
    else if ((*iter)->getWidgetType() == "ButtonLabel")
      return std::dynamic_pointer_cast<ButtonLabel>(*iter);
    else if ((*iter)->getWidgetType() == "Menu")
      return std::dynamic_pointer_cast<Menu>(*iter);
  }
}

auto type = SceneManager::getCurrentScene().m_gui.getType(widgetId);

SceneManager::getCurrentScene().m_gui.getWidget<decltype(type)>(widgetId)->attachToMenu(getId());
模板
std::共享的ptr
getWidget(const std::string&id){
自动iter=findObject(id);
if(iter!=m_widgets.end())返回std::dynamic_pointer_cast(*iter);
返回空ptr;
}
常量小部件::Ptr
getType(const std::string&id){
自动iter=findObject(id);
if(iter!=m_widgets.end()){
如果((*iter)->getWidgetType()==“标签”)
返回标准::动态指针投射(*iter);
else if((*iter)->getWidgetType()=“Editbox”)
返回标准::动态指针投射(*iter);
else if((*iter)->getWidgetType()==“按钮标签”)
返回标准::动态指针投射(*iter);
如果((*iter)->getWidgetType()=“菜单”)
返回标准::动态指针投射(*iter);
}
}
auto type=SceneManager::getCurrentScene().m_gui.getType(widgetId);
SceneManager::getCurrentScene().m_gui.getWidget(widgetId)->attachToMenu(getId());
Widget::Ptr
只是一个
typedef std::shared\u Ptr
。如您所见,
m_widgets
是一个列表,其中填充了widgets,这些widgets是一个基类,
Label
EditBox
ButtonLabel
,菜单都是从中派生出来的。我试图向下转换到这些类,以便获得类型,并使用我的
getWidget()
编辑派生对象。但是,我遇到了以下错误:

错误:“类std::shared_ptr”没有名为“attachToMenu”的成员|

这显然意味着它没有正确地进行强制转换,并且返回了一个小部件。任何帮助都会很好,谢谢

“Widget::Ptr只是一个typedef std::shared\u Ptr。”

我假设它是
std::shared\u ptr
的typedef。如果是这样,则
dynamic\u pointer\u cast
仅在函数体内部向下转换,其类型外部为
std::shared\u ptr
(这是因为返回类型意味着向上转换):

当你申报时

auto type = ...

type
的类型将始终是
Widget::Ptr
,因为这是函数返回的类型。所有向下转换都发生在函数内,因此不重要。然后,当您使用
decltype(type)
调用
getWidget
时,将使用静态类型,因此再次使用
Widget::Ptr
。您需要重新设计。

iter==m_widgets.end()的情况下,您有未定义的行为。
。在这种情况下,可能需要添加
return nullptr
。您认为
decltype(type)
是什么?如果我读得正确,
decltype(type)
是一个
std::shared\u ptr
,因此
getWidget
返回一个
std::shared\u ptr
,并调用
->attachToMenu(…)
这是一个禁忌。悲观情绪很好。
getType
的返回类型导致向上投射到
Widget::Ptr
class Widget
{
public:
    virtual ~Widget() = default;
    virtual void attachToMenu(const std::string& id) = 0;
};

class EditBox : public Widget
{
public:
    virtual void attachToMenu(const std::string& id) override
    {
        // do the stuff
    }
};

std::shared_ptr<Widget> widget = std::make_shared<EditBox>();
widget->attachToMenu(getId()); // calls EditBox::attachToMenu
auto type = ...