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
-
auto
define un tipo de iterador para el niño, determinado estáticamente por el compilador (no puede cambiar entre llamadas). - el tipo de
child
es la asignación compatible conrbegin()
yrend()
- el tipo de
child
es 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
child
no 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
this
en el primer caso podría ser diferente del capturado en el enlace (clase base frente a clase derivada, por ejemplo) - El valor de
this
se 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.