我可以默认第一个模板参数吗?

时间:2016-10-04 13:53:10

标签: c++ templates argument-deduction

我有一个带有两个typename参数的模板方法(它实际上是QObject::connect() - 请参阅this answeranother answer)。因为类型名是针对成员指针的,所以当传入的名称引用重载函数时,演绎可能会失败;当发生这种情况时,我们需要将一个参数强制转换为正确的类型(可能将其存储到所需类型的局部变量中),或者使用一个或多个模板参数限定调用。

以其中一个相关问题为例:

QObject::connect(spinBox, &QSpinBox::valueChanged,
                 slider, &QSlider::setValue);

需要写成

QObject::connect<void(QSpinBox::*)(int)>(spinBox, &QSpinBox::valueChanged,
                                         slider, &QSlider::setValue);

或(通过胁迫):

void(QSpinBox::*signal)(int) = &QSpinBox::valueChanged;
QObject::connect(spinBox, signal,
                 slider, &QSlider::setValue);

但是,有时候,可以推导出第一个模板参数,但后面的参数是必需的。是否有一种简单的方法来默认第一个参数,但是指定其他参数?我在考虑像

这样的东西
QObject::connect<auto, void(QSpinBox::*)(int)>(slider, &QSlider::valueChanged,
                                               spinBox, &QSpinBox::setValue);

显然,这不是有效的C ++,但我希望它说明了这一点。

我知道我可以写

void(QSpinBox::*slot)(int) = &QSpinBox::setValue;
QObject::connect(slider, &QSlider::valueChanged,
                 spinBox, slot);

但我希望语法更简洁。

1 个答案:

答案 0 :(得分:7)

  

是否有一种简单的方法来默认第一个参数,但是指定其他参数?

没有。你只需要手动强制第二个参数,就像使用static_cast

一样
QObject::connect(slider, &QSlider::valueChanged,
    spinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::setValue));

或者只使用connect()的不同重载并传递lambda:

QObject::connect(slider, &QSlider::valueChanged,
    [&spinBox](int i){ spinBox.setValue(i); });