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

C++ 我可以默认第一个模板参数吗?,c++,templates,template-argument-deduction,C++,Templates,Template Argument Deduction,我有一个带有两个typename参数的模板方法(实际上是QObject::connect()-请参阅和)。因为类型名用于成员指针,当传入的名称引用重载函数时,演绎可能会失败;发生这种情况时,我们需要将一个参数强制为正确的类型(可能通过将其存储到所需类型的局部变量中),或者使用一个或多个模板参数限定调用 以链接问题中的一个为例: QObject::connect(spinBox, &QSpinBox::valueChanged, slider, &

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

以链接问题中的一个为例:

QObject::connect(spinBox, &QSpinBox::valueChanged,
                 slider, &QSlider::setValue);
需要写为

QObject::connect<void(QSpinBox::*)(int)>(spinBox, &QSpinBox::valueChanged,
                                         slider, &QSlider::setValue);
虽然有时可以推导出第一个模板参数,但需要一个更晚的模板参数。是否有一种简单的方法来默认第一个参数,但指定其他参数?我在想类似的事情

QObject::connect<auto, void(QSpinBox::*)(int)>(slider, &QSlider::valueChanged,
                                               spinBox, &QSpinBox::setValue);
但我希望有一个更简洁的语法

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

不需要。您只需手动强制第二个参数,就像使用
静态\u cast

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

我认为您应该能够通过静态转换将函数转换为所需的指针类型。类似于
static\u cast(QSpinBox::setValue)
。这应该允许模板参数推断工作,因此您不需要指定类型。好吧,这更难看-我更喜欢定义一个合理的
up\u cast()
,它更安全(并且在不缩小范围的情况下强制
?:
的参数也很有用)。我怀疑答案可能是“否”,但似乎值得一问。“那么,我将坚持使用局部变量方法作为最干净的方法。”TobySpeight不喜欢lambda方法?不特别喜欢,但这是主观的。我不会在代码审查中反对它,但我也很少自己编写它。也许我想象的开销比兰姆达斯实际招致的开销要大得多!在这里您确实需要小心,因为您已经巧妙地将连接类型参数从“auto”更改为“direct”——这在UI->UI连接中不是问题,但在跨线程时可能会有问题。
void(QSpinBox::*slot)(int) = &QSpinBox::setValue;
QObject::connect(slider, &QSlider::valueChanged,
                 spinBox, slot);
QObject::connect(slider, &QSlider::valueChanged,
    spinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::setValue));
QObject::connect(slider, &QSlider::valueChanged,
    [&spinBox](int i){ spinBox.setValue(i); });