QT:将信号连接到具有移动语义的插槽

QT: Connect signals to slots with move semantics

本文关键字:移动 语义 插槽 信号 连接 QT      更新时间:2023-10-16

好吧,我有类似的东西:

void EmailReceiverThread::foreachEmailAccount(ConfigEmailAccount account)
{
    Email email;
    EmailReader emailReader(account);
    while (emailReader.pollEmail(email))
    {
        writeEmailToDatabase(email);
    }
}

foreachEmailAccount是EmailReceiverThread中的一个插槽。从run()方法称为

GetConfigEmailDAO* accountReader = new GetConfigEmailDAO(type, m_channel);
connect(accountReader, SIGNAL(emailAccount(ConfigEmailAccount)),
        this, SLOT(foreachEmailAccount(ConfigEmailAccount)), Qt::QueuedConnection);
DbThread::postAction(accountReader);

getConfigemaildao进行查询,获取电子邮件帐户并进行发射:

emit emailAccount(account);

这是迄今为止的工作。问题是,我正在复制类ConfigemailAccount。我想避免这种打击。因此,我的想法是使用C 11移动语义发射帐户:

emit emailAccount(std::move(account));

我用新的语法重写了插槽和信号:

void foreachEmailAccount(ConfigEmailAccount&& account);

不幸的是,这无效。我有下一个汇编错误:

moc_emailreceiverthread.cpp:88: error: cannot bind ‘ConfigEmailAccount’ lvalue to ‘ConfigEmailAccount&&’
     case 1: _t->foreachEmailAccount((*reinterpret_cast< ConfigEmailAccount(*)>(_a[1]))); break;

我该怎么办?

最小可验证的示例在这里:

#include <QCoreApplication>
#include <QObject>
class ConfigEmailAccount
{
    QString some_data;
};
class GetConfigEmailDAO : public QObject
{
    Q_OBJECT
public:
    void execute();
signals:
    void emailAccount(ConfigEmailAccount&& account);
};
void GetConfigEmailDAO::execute()
{
    ConfigEmailAccount account;
    emit emailAccount(std::move(account));
}
class EmailReceiverThread : public QObject
{
    Q_OBJECT
public:
    void execute();
public slots:
    void foreachEmailAccount(ConfigEmailAccount&& account);
};
void EmailReceiverThread::execute()
{
    GetConfigEmailDAO* accountReader = new GetConfigEmailDAO;
    connect(accountReader, SIGNAL(emailAccount(ConfigEmailAccount)),
            this, SLOT(foreachEmailAccount(ConfigEmailAccount)), Qt::QueuedConnection);
    accountReader->execute();
}
void EmailReceiverThread::foreachEmailAccount(ConfigEmailAccount&& account)
{
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qRegisterMetaType<ConfigEmailAccount>("ConfigEmailAccount");
    EmailReceiverThread reader;
    reader.execute();
    return a.exec();
}
#include "main.moc"

最后,我采用了QT的浅复制机制:
http://doc.qt.io/qt-5.6/qshareddatapointer.html#details