ここでの問題は、その名前の 2 つの信号があることです:QSpinBox::valueChanged(int)
とQSpinBox::valueChanged(QString)
. Qt 5.7 から、必要なオーバーロードを選択するためのヘルパー関数が提供されているため、次のように記述できます。
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
Qt 5.6 以前では、正しいタイプにキャストして、どちらを選択するかを Qt に伝える必要があります。
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
私は知っています、それは醜いです。しかし、これを回避する方法はありません。今日のレッスンは:シグナルとスロットを過負荷にしないでください!
補遺: キャストについて本当に厄介なのは、
- 1 つはクラス名を 2 回繰り返します
void
通常(シグナルの場合)であっても、戻り値を指定する必要があります。
そのため、この C++11 スニペットを使用することがあります。
template<typename... Args> struct SELECT {
template<typename C, typename R>
static constexpr auto OVERLOAD_OF( R (C::*pmf)(Args...) ) -> decltype(pmf) {
return pmf;
}
};
使用法:
connect(spinbox, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged), ...)
個人的にはあまり役に立たないと思います。Creator (または IDE) が PMF の取得操作をオートコンプリートするときに正しいキャストを自動的に挿入すると、この問題は自然に解消されると思います。しかし、その間...
注: PMF ベースの接続構文には C++11 は必要ありません。
補遺 2 : Qt 5.7 では、上記の回避策をモデルにして、これを軽減するためにヘルパー関数が追加されました。主なヘルパーはqOverload
( と も持っていますqConstOverload
)qNonConstOverload
です。
使用例(ドキュメントから):
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)
補遺 3 : オーバーロードされた信号のドキュメントを見ると、オーバーロードの問題の解決策がドキュメント自体に明確に記載されています。たとえば、https://doc.qt.io/qt-5/qspinbox.html#valueChanged-1は言う
注: シグナル valueChanged は、このクラスでオーバーロードされます。関数ポインター構文を使用してこのシグナルに接続するために、Qt は次の例に示すように、関数ポインターを取得するための便利なヘルパーを提供します。
connect(spinBox, QOverload<const QString &>::of(&QSpinBox::valueChanged),
[=](const QString &text){ /* ... */ });