I have a template method with two typename parameters (it's actually QObject::connect()
- see this answer and another answer). Because the typenames are for member pointers, deduction can fail when the name passed in refers to an overloaded function; when that happens, we need to either coerce one argument to the correct type (perhaps by storing it into a local variable of the desired type) or to qualify the call with one or more of the template parameters.
Taking an example from a one of the linked questions:
QObject::connect(spinBox, &QSpinBox::valueChanged,
slider, &QSlider::setValue);
needs to be written as
QObject::connect<void(QSpinBox::*)(int)>(spinBox, &QSpinBox::valueChanged,
slider, &QSlider::setValue);
or (by coercing):
void(QSpinBox::*signal)(int) = &QSpinBox::valueChanged;
QObject::connect(spinBox, signal,
slider, &QSlider::setValue);
Sometimes, though, the first template argument could be deduced, but a later one is required. Is there an easy way to default the first parameter, but specify others? I was thinking of something like
QObject::connect<auto, void(QSpinBox::*)(int)>(slider, &QSlider::valueChanged,
spinBox, &QSpinBox::setValue);
Obviously, that's not valid C++, but I hope it illustrates the point.
I know I can write
void(QSpinBox::*slot)(int) = &QSpinBox::setValue;
QObject::connect(slider, &QSlider::valueChanged,
spinBox, slot);
but I'm hoping for a more concise syntax.
Is there an easy way to default the first parameter, but specify others?
No. You'll just have to coerce the second argument manually, like with a static_cast
:
QObject::connect(slider, &QSlider::valueChanged,
spinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::setValue));
Or just use a different overload of connect()
and pass a lambda:
QObject::connect(slider, &QSlider::valueChanged,
[&spinBox](int i){ spinBox.setValue(i); });