Connecting overloaded signals and slots in Qt 5
Connecting overloaded signals and slots in Qt 5
There are two signals with that name:
QSpinBox::valueChanged(int) and QSpinBox::valueChanged(QString)
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged), slider, &QSlider::setValue);
By using this:
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), slider, &QSlider::setValue);
Procedure 1:
- One rpeats the class name twice
- One has to specify the return value even if it’s usually void (for signals).
In c++snippet:
template<typename... Args> struct SELECT { template<typename C, typename R> static constexpr auto OVERLOAD_OF( R (C::*pmf)(Args...) ) -> decltype(pmf) { return pmf; } };
Try it:
connect(spinbox, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged), ...)
It will insert in the right cast when autocompleting the operation of taking the PMF.
Procedure2:
The main link is qOverload , qConstOverload and qNonConstOverload).
Main example:
struct Foo { void overloadedFunction(); void overloadedFunction(int, QString); }; // requires C++14 qOverload<>(&Foo:overloadedFunction) qOverload<int, QString>(&Foo:overloadedFunction) // same, with C++11 QOverload<>::of(&Foo:overloadedFunction) QOverload<int, QString>::of(&Foo:overloadedFunction)
In simple words:
The most important “unresolved overloaded function type”. The compiler doesn’t know whether you mean QSpinBox::valueChanged(int) or QSpinBox::valueChanged(QString).
Easy way to solve the overload:
The given template parameter to connect()
QObject::connect<void(QSpinBox::*)(int)>(spinBox, &QSpinBox::valueChanged, slider, &QSlider::setValue);
To connect() the resolve &QSpinBox::valueChanged into the overload that takes an int.
To unresolved the overloads of slot argument, then must need to supply the second template argument to connect(). The first is to be inferred, to Apply both. when the second approach will use:
The temporary variable
void(QSpinBox::*signal)(int) = &QSpinBox::valueChanged; QObject::connect(spinBox, signal, slider, &QSlider::setValue);
The signal will select the desired overload, and now it can be substituted successfully into the template.
In conversion method
They avoid static_cast to removal of the language’s protections:
// Also useful for making the second and // third arguments of ?: operator agree. template<typename T, typename U> T&& coerce(U&& u) { return u; }
By using this code:
QObject::connect(spinBox, coerce<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), slider, &QSlider::setValue);
Use this slot:
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), slider, &QSlider::setValue);