C++ std::remove不是从std::vector中删除

C++ std::remove不是从std::vector中删除,c++,std,C++,Std,这是我的问题: 在我的GUI中,有几种类型的侦听器。它们存储在std::vector 在我的GUI中,我有一个名为RemovelListeners的方法,它如下所示: void Widget::removeListeners( Widget* widget ) { removeFocusListener((FocusListener*)widget); removeMouseListener((MouseListener*)widget); removeKeyboardL

这是我的问题: 在我的GUI中,有几种类型的侦听器。它们存储在
std::vector

在我的GUI中,我有一个名为
RemovelListeners
的方法,它如下所示:

void Widget::removeListeners( Widget* widget )
{
    removeFocusListener((FocusListener*)widget);
    removeMouseListener((MouseListener*)widget);
    removeKeyboardListener((KeyboardListener*)widget);
    removeWidgetListener((WidgetListener*)widget);
}
void Widget::removeWidgetListener( 
                                    WidgetListener *listener )
{
    widgetListeners.erase(
        std::remove(widgetListeners.begin(),
        widgetListeners.end(), listener),
        widgetListeners.end());
}
基本上,我不认为我怎么投它有什么关系;它们只是指针。我认为
std::remove
只是比较指针,因此如果我提供一个小部件*,那么它应该不会影响任何东西(我认为)

移除函数的外观如下所示:

void Widget::removeListeners( Widget* widget )
{
    removeFocusListener((FocusListener*)widget);
    removeMouseListener((MouseListener*)widget);
    removeKeyboardListener((KeyboardListener*)widget);
    removeWidgetListener((WidgetListener*)widget);
}
void Widget::removeWidgetListener( 
                                    WidgetListener *listener )
{
    widgetListeners.erase(
        std::remove(widgetListeners.begin(),
        widgetListeners.end(), listener),
        widgetListeners.end());
}
因此,在小部件析构函数中,我遍历小部件的子部件并调用
RemovelListeners()


那么,为什么一个有效而另一个无效呢?我发现的唯一区别是,在第一个示例中,我将一个小部件转换为该类型。但我认为它只会比较指针,如果它们是==它就会删除它?

我担心您可能会被C中的对象标识和虚拟基类刺痛++

基本上,将指针转换为多态性基并不能保证得到相同的指针值(例如,当转换为(void*)时)


只要您存储的指针类型与在删除过程中强制转换的指针类型完全相同,它就应该可以工作,但如果不查看更多的代码/小部件类层次结构,我无法确定。问题的根源似乎是设计不正确。需要在您正在执行时进行强制转换意味着函数位于错误的位置。从你的帖子中还不清楚小部件和不同类型的侦听器类之间的关系

您需要重新考虑从何处调用RemovelListeners函数,而不是将其放在基类析构函数中,您应该将其放在类的析构函数中,该类实际上知道它是哪种类型的侦听器(并且只调用正确的侦听器)


如果不了解类之间关系的更多细节,就很难更加具体。一般来说,如果您必须强制转换,您应该问问自己是否有更好的方法来完成强制转换的任务。

强制转换告诉编译器“我知道这个变量的类型,即使您不知道。”您不应该将指针强制转换到一个不真实的类型。每个
Widget*
是否同时传递给
removeListeners()
焦点、鼠标、键盘和Widget侦听器?最好修改标题,提及
erase
,因为我和其他人最初认为这只是另一个不理解
remove
如何工作的问题@Xeo:是的,我在读这篇文章之前就已经输入了答案,然后在5秒内删除了:)所以我应该在删除之前动态地强制转换,然后再删除,是的,但只能按照你插入的确切类型。我个人认为铸件是一种气味,但你绝对应该考虑这种情况下的动态铸件。