我的GUI的模板化小部件系统出现问题

时间:2014-08-22 18:15:32

标签: c++ templates pointers user-interface widget

我先发布我的代码然后解释我的问题:

    std::list<Widget::Ptr> m_widgets;

    std::list<Widget::Ptr>::iterator findObject(const std::string& id)
    {
        for (auto iter = m_widgets.begin(); iter != m_widgets.end(); ++iter)
        {
            if ((*iter)->getId() == id)
                return iter;
        }

        return m_widgets.end();
    }

    template <class T> void pushWidget(std::shared_ptr<T> widget)
    {
        auto iter = findObject(widget->getId());

        if (iter != m_widgets.end())
            return;

        m_widgets.push_back(std::dynamic_pointer_cast<Widget>(widget));
    }

    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 std::type_index& getType(const std::string& id)
    {
        auto iter = findObject(id);

        if (iter != m_widgets.end())
            return typeid(*iter);
    }

Widget :: Ptr是std :: shared_ptr的typedef顺便说一下。无论如何,我遇到的问题是如何告诉getWidget()小部件是什么类型的小部件。 Widget是其他小部件继承的基类,例如Label,Editbox等。对于我的主GUI管理器,我尽可能地缩短我的代码以使更新/绘图尽可能干净。现在,菜单是我在这种情况下尝试使用的一种小部件:

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

SceneManager::getCurrentScene().m_gui.getWidget<typeid(type)>(widgetId)->attachToMenu(getId());

但是,这不起作用,我从编译器中收到这些错误:

error: no matching function for call to 'SE::GUI::getWidget(const string&)'|
note: candidate is:|
note: template<class T> std::shared_ptr<_Tp> SE::GUI::getWidget(const string&)|
note:   template argument deduction/substitution failed:|

我可以提供所需的更多详细信息,并感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

typeid(type)不返回表达式type的类型,但返回有关类型(RTTI)的运行时信息。你想要的是decltype(),它返回一个表达式的类型:

SceneManager::getCurrentScene().m_gui.getWidget<decltype(type)>(widgetId)->attachToMenu(getId());