为什么Qt在信号和插槽中为lambda表达式抛出错误?

时间:2018-06-21 11:19:29

标签: c++ qt lambda

我有一个功能(公共插槽)

void Parts::Testing(QString text)
{
    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
}

与QCompleter的信号连接为

connect(completer_part_invoice, SIGNAL(activated(QString)),
                    this, SLOT(Testing(QString)));

以上代码的目的是,每当我使用QCompleter中的complete()函数时,建议就会在行编辑中弹出,并且在单击建议时,特定的文本应出现在行编辑中。

上面的代码符合我的预期

问题 由于该函数只有一条语句,因此我想在connect函数本身中使用lambda表达式。从而节省代码长度并提高可读性。 谷歌搜索后,我发现了this。引用该网站后,我编写了这样的代码

尝试1

connect(
    completer_part_invoice, &QCompleter::activated,
    [&]( const QString &text )
    {
    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
});

但是Qt抛出了错误

error: no matching function for call to 'Parts::connect(QCompleter*&, <unresolved overloaded function type>, Parts::pop_Up_Invoices()::<lambda(const QString&)>)'
             );
         ^

尝试2

connect(
    completer_part_invoice, SIGNAL(activated(QString)),
    [&]( const QString &text )
    {
    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
});

但是Qt抛出了错误

error: no matching function for call to 'Parts::connect(QCompleter*&, const char [20], Parts::pop_Up_Invoices()::<lambda(const QString&)>)'
             });
              ^

请有人能指出我做错了什么吗?

PS 如果我犯了任何错误,请告诉我,不要拒绝投票

修改

Try3 正如评论中指出的,我也尝试过

connect(
    completer_part_invoice, QOverload<const QString &>(&QCompleter::activated),
    [&](const QString &text)->void
    {
    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
});

我遇到错误

 error: no matching function for call to 'QOverload<const QString&>::QOverload(<unresolved overloaded function type>)'
                 completer_part_invoice, QOverload<const QString &>(&QCompleter::activated), 

                                                                                    ^

4 个答案:

答案 0 :(得分:2)

使用新调用语法的方式使其模棱两可。比较:

connect(obj, SIGNAL(activated(QString)), ...)

使用

connect(obj, &Class::activated, ...)

缺少关于activated的类型信息,编译器必须扣除它。问题是:该方法有两个重载:

void C::activated(const QString &text)
void C::activated(const QModelIndex &index)

使用更先进的模板设备,可以使connect根据连接的接收方类型选择过载。但是尚未实现。这就是Qt提供QOverloadqOverload的原因,因此您不必自己编写笨拙的演员表。以下所有版本均等效; qOverload有点儿冗长,但是需要更新的编译器。 QOverload适用于当前Qt支持的所有编译器。

connect(obj, QOverload<QString>::of(&Class::activated), ...)
connect(obj, qOverload<QString>(&Class::activated), ...)
connect(obj, static_cast<void(Class::*)(const QString&)>(&Class::activated), ...)

答案 1 :(得分:2)

这是因为QCompleter有两个activated重载。您需要指定要使用的那个:

connect(completer_part_invoice, QOverload<const QString&>::of(&QCompleter::activated),
    this, [&](const QString& text) {
        ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
});

实际上是in the docs::of之后,您的 Try 3 丢失了QOverload<const QString &>

答案 2 :(得分:1)

最后,经过评论中提到的答案的反复试验后,我能够进行编译而没有错误,并且有效

        connect(
            completer_part_invoice, static_cast<void (QCompleter::*)(const QString&)>(&QCompleter::activated),
            [&](const QString &text)->void
            {
            ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
        });

谢谢大家

编辑:如评论和其他答案所述,我在尝试3中缺少“ of” 现在这也有效

        connect(completer_part_invoice, 
                QOverload<const QString&>::of(&QCompleter::activated),
            this, [&](const QString& text) {
                ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
        });

答案 3 :(得分:0)

尝试从此部分中删除const (const QString&text)