connect with/without lambda - why not equivalent?
-
class DoubleSpinBox : public QAbstractSpinBox { void f(); void g() { ... connect(x, &X::sig, this, &DoubleSpinBox::f); // or connect(x, &X::sig, [this] { f(); }); } }
Aren't these two forms of the
connect
function equivalent? In a complex code, the first form works, while the second causes a segfault(gdb) p this $3 = (DoubleSpinBox * const) 0x555557178fc0 (gdb) p *this $4 = {<QAbstractSpinBox> = {<No data fields>}, static staticMetaObject = {d = {superdata = { direct = 0x7ffff76eea00 <QAbstractSpinBox::staticMetaObject>}, stringdata = 0x7ffff7d053a0 <(anonymous namespace)::qt_meta_stringdata_DoubleSpinBox>, data = 0x7ffff7d05340 <qt_meta_data_DoubleSpinBox>, static_metacall = 0x7ffff7a48740 <DoubleSpinBox::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, metaTypes = 0x7ffff7ed1860 <qt_incomplete_metaTypeArray<(anonymous namespace)::qt_meta_stringdata_DoubleSpinBox_t, QtPrivate::TypeAndForceComplete<DoubleSpinBox, std::integral_constant<bool, true> >, QtPrivate::TypeAndForceComplete<void, std::integral_constant<bool, false> >, QtPrivate::TypeAndForceComplete<double, std::integral_constant<bool, false> > >>, extradata = 0x0}}, m_property = 0x55555718d4f0, m_old_dir = 0, m_step = 0.10000000000000001}
How can it ever happen that the parent class has
<No data fields>
? -
The problem in my code was a hidden
disconnect
statement.To close this thread properly, let me summarize what I understood from the docs: The two forms are perfectly equivalent as long as sender and receiver are alive. They differ in how they react to destruction of the receiver: A connection established through form 1 will automatically be deleted, which is not the case for form 2, hence the segfault when
this->f
is called thoughthis
no longer exists. -
class DoubleSpinBox : public QAbstractSpinBox { void f(); void g() { ... connect(x, &X::sig, this, &DoubleSpinBox::f); // or connect(x, &X::sig, [this] { f(); }); } }
Aren't these two forms of the
connect
function equivalent? In a complex code, the first form works, while the second causes a segfault(gdb) p this $3 = (DoubleSpinBox * const) 0x555557178fc0 (gdb) p *this $4 = {<QAbstractSpinBox> = {<No data fields>}, static staticMetaObject = {d = {superdata = { direct = 0x7ffff76eea00 <QAbstractSpinBox::staticMetaObject>}, stringdata = 0x7ffff7d053a0 <(anonymous namespace)::qt_meta_stringdata_DoubleSpinBox>, data = 0x7ffff7d05340 <qt_meta_data_DoubleSpinBox>, static_metacall = 0x7ffff7a48740 <DoubleSpinBox::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, metaTypes = 0x7ffff7ed1860 <qt_incomplete_metaTypeArray<(anonymous namespace)::qt_meta_stringdata_DoubleSpinBox_t, QtPrivate::TypeAndForceComplete<DoubleSpinBox, std::integral_constant<bool, true> >, QtPrivate::TypeAndForceComplete<void, std::integral_constant<bool, false> >, QtPrivate::TypeAndForceComplete<double, std::integral_constant<bool, false> > >>, extradata = 0x0}}, m_property = 0x55555718d4f0, m_old_dir = 0, m_step = 0.10000000000000001}
How can it ever happen that the parent class has
<No data fields>
?@Joachim-W said in connect with/without lambda - why not equivalent?:
connect(x, &X::sig, [&] { f(); });
Don't forget that
[&]
passes all local variables by reference. If this is not your real code and your lambda accesses one of them, they would eb out-of-scope by the time the signal/slot connection activates. Could this be relevant to your situation? -
@Joachim-W said in connect with/without lambda - why not equivalent?:
connect(x, &X::sig, [&] { f(); });
Don't forget that
[&]
passes all local variables by reference. If this is not your real code and your lambda accesses one of them, they would eb out-of-scope by the time the signal/slot connection activates. Could this be relevant to your situation? -
@JonB I edited the question to replace
[&]
by[this]
- same error though no other variables are captured.The second will crash as soon as DoubleSpinBox is destroyed but x is still alive and emitting the signal as you don't pass a context to the connect function. The 3-arg connect() should therefore be avoided.
-
The problem in my code was a hidden
disconnect
statement.To close this thread properly, let me summarize what I understood from the docs: The two forms are perfectly equivalent as long as sender and receiver are alive. They differ in how they react to destruction of the receiver: A connection established through form 1 will automatically be deleted, which is not the case for form 2, hence the segfault when
this->f
is called thoughthis
no longer exists. -