the one objects more failed drop dependent column because c++ qt c++11

c++ - dependent - alter table drop column failed because one or more objects access this column



objeto temporal en el rango de base para (2)

Como está usando C ++ 11, podría usar la lista de inicialización . Esto pasará valgrind:

int main() { for (auto i : QList<int>{1, 2, 3}) std::cout << i << std::endl; return 0; }

El problema no está totalmente relacionado con el rango basado para C ++ 11, ni siquiera. El siguiente código demuestra el mismo problema:

QList<int>& things = QList<int>() << 1; things.end();

o:

#include <iostream> struct S { int* x; S() { x = NULL; } ~S() { delete x; } S& foo(int y) { x = new int(y); return *this; } }; int main() { S& things = S().foo(2); std::cout << *things.x << std::endl; return 0; }

La lectura no válida se debe a que el objeto temporal de la expresión S() (o QList<int>{} ) se destruye después de la declaración (después de C ++ 03 y C ++ 11 §12.2 / 5), porque el compilador no tiene idea de que el método foo() (u operator<< ) devolverá ese objeto temporal. Así que ahora te refieres al contenido de la memoria liberada.

Sé que, en general, el tiempo de vida de un temporal en un bucle for basado en rango se extiende a todo el bucle (he leído C ++ 11: ¿El tiempo de vida "range-init"? ). Por lo tanto, hacer cosas como esta generalmente está bien:

for (auto &thingy : func_that_returns_eg_a_vector()) std::cout << thingy;

Ahora estoy tropezando con los problemas de memoria cuando intento hacer algo que pensé que era similar con el contenedor QList de Qt:

#include <iostream> #include <QList> int main() { for (auto i : QList<int>{} << 1 << 2 << 3) std::cout << i << std::endl; return 0; }

El problema aquí es que valgrind muestra acceso de memoria no válido en algún lugar dentro de la clase QList . Sin embargo, modificar el ejemplo para que la lista se almacene en una variable proporciona un resultado correcto:

#include <iostream> #include <QList> int main() { auto things = QList<int>{} << 1 << 2 << 3; for (auto i : things) std::cout << i << std::endl; return 0; }

Ahora mi pregunta es: ¿estoy haciendo algo tonto en el primer caso que resulta en, por ejemplo, un comportamiento indefinido (no tengo suficiente experiencia en la lectura del estándar de C ++ para responder esto por mí mismo)? ¿O es esto un problema con la forma en que uso QList o con cómo se implementa QList ?


El compilador no puede saber que la referencia que es el resultado de tres llamadas al operator << está vinculada al objeto temporal QList<int>{} , por lo que la vida del temporal no se extiende. El compilador no sabe (y no se puede esperar que sepa) nada sobre el valor de retorno de una función, excepto su tipo. Si es una referencia, no sabe a qué puede unirse. Estoy bastante seguro de que, para que la regla de extensión de la vida se aplique, el enlace debe ser directo.

Esto debería funcionar porque la lista ya no es temporal:

#include <iostream> #include <QList> int main() { auto things = QList<int>{}; for (auto i : things << 1 << 2 << 3) std::cout << i << std::endl; return 0; }

Y esto debería funcionar porque el enlace es directo, por lo que la regla puede aplicarse:

#include <iostream> #include <QList> int main() { for (auto i : QList<int>{1, 2, 3}) std::cout << i << std::endl; return 0; }