C++ 我的GUI有问题';s模板小部件系统

C++ 我的GUI有问题';s模板小部件系统,c++,templates,pointers,user-interface,widget,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) {

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

    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);
    }
std::列出m_小部件;
std::list::迭代器findObject(const std::string&id)
{
for(auto iter=m_widgets.begin();iter!=m_widgets.end();++iter)
{
如果((*iter)->getId()==id)
返回iter;
}
返回m_widgets.end();
}
模板void pushWidget(std::shared_ptr widget)
{
auto iter=findObject(widget->getId());
if(iter!=m_widgets.end())
返回;
m_widgets.push_back(std::dynamic_pointer_cast(widget));
}
模板std::shared_ptr getWidget(const std::string&id)
{
自动iter=findObject(id);
if(iter!=m_widgets.end())
返回标准::动态指针投射(*iter);
返回空ptr;
}
const std::type_index&getType(const std::string&id)
{
自动iter=findObject(id);
if(iter!=m_widgets.end())
返回类型ID(*iter);
}
顺便说一下,Widget::Ptr是std::shared_Ptr的typedef。无论如何,我遇到的问题是如何告诉getWidget()小部件是什么类型的小部件。Widget是其他Widget继承的基类,例如Label、Editbox等。对于我的主GUI管理器,我正在尽可能缩短代码,以使更新/绘图尽可能干净。现在,菜单是我在本例中尝试使用的一种小部件:

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

SceneManager::getCurrentScene().m_gui.getWidget<typeid(type)>(widgetId)->attachToMenu(getId());
auto-type=SceneManager::getCurrentScene().m_gui.getType(widgetId);
SceneManager::getCurrentScene().m_gui.getWidget(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:|
错误:调用'SE::GUI::getWidget(const string&')没有匹配的函数|
注:候选人为:|
注意:模板std::shared_ptr SE::GUI::getWidget(常量字符串&)|
注意:模板参数扣除/替换失败:|
我可以提供任何更多的细节,需要,并感谢任何和所有的帮助

typeid(type)
不返回表达式的类型
type
,而是返回有关该类型的运行时信息(RTTI)。您需要的是
decltype()
,它返回表达式的类型:

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

不要使用
std::list
,使用
std::vector
。这可以提高你的表现。实际上,您的意思是
decltype(type)
,而不是
typeid(type)
谢谢您的回答,但不幸的是,当我运行此代码时,我遇到了以下错误:“struct std::type\u index”没有名为“attachToMenu”的成员