for_each - vector c++ español
¿Por qué obtengo el error ''iterators vector incompatibles''? (1)
Estoy escribiendo una IU pequeña para mi programa. Tengo el método onMouseMotion() , que puedo llamar de una de dos maneras (ver código); si lo llamo a través de std::function , entonces != operator en la condición for stop stop produce que los vector iterators incompatible excepción en tiempo de ejecución sean vector iterators incompatible . ¿Por qué?
class Widget : public EventHandler
{
protected:
/* ... */
std::vector<Widget *> children_;
std::function<bool(Event &)> func_;
private:
bool onMouseMotion(Event &event);
/* ... */
};
Widget::Widget()
{
/* ... */
func_ = std::bind(&Widget::onMouseMotion, this, std::placeholders::_1);
/* ... */
}
bool Widget::processEvent(Event &event)
{
if (event.getType() == ui::EventType::MouseMotionEvent) {
/* Method 1 - onMouseMotion works ok */
onMouseMotion(event);
/* Method 2 - onMouseMotion throws */
//func_(event);
return true;
}
}
bool Widget::onMouseMotion(Event &event)
{
/* exception occurs on the next line, only when using Method 2 above */
for (auto child = children_.rbegin(); child != children_.rend(); ++child) {}
}
Actualizaciones :
- el programa es de un solo hilo.
- la excepción se produce al ingresar el ciclo
for, ocurren iteraciones cero. - compilando con MSVC.
- misma excepción con un bucle vacío
for. - ejemplos reescritos para ilustrar el problema
std::function.
Entonces, está claro que
-
autodefine un tipo de iterador para el niño, determinado estáticamente por el compilador (no puede cambiar entre llamadas). - el tipo de
childes la asignación compatible conrbegin()yrend() - el tipo de
childes un operador relacional compatible conrbegin()cuando se llama directamente, pero no cuando se llama a través de la envolturabind() - ya que el tipo de
childno puede cambiar, el tipo derend()debe tener, en el segundo caso.
Veo las siguientes posibilidades.
- El vector es un miembro y, por lo tanto, el tipo de iterador será un puntero al miembro, y el puntero al miembro tiene algunas restricciones sobre cómo se puede usar.
- El valor de
thisen el primer caso podría ser diferente del capturado en el enlace (clase base frente a clase derivada, por ejemplo) - El valor de
thisse puede entregar a través de un contenedor, que cambia su comportamiento de tipo.
En general, es más probable que se trate de un error de MSVC. El código proporcionado no se compila y soy reacio a intentar modificarlo y es probable que no pueda reproducir el error. Si puede publicar un caso de repro que compila, con gusto investigaremos más y actualizaremos la respuesta.