2017-10-02 20 views
0

Ok, j'ai quelque chose comme ceci:QT: connecter des signaux à fentes avec une sémantique de déplacement

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

ForeachEmailAccount est une fente en EmailReceiverThread. Il est appelé à partir de la course() méthode:

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

GetConfigEmailDAO fait une requête, récupérer le compte de messagerie et faire la Emit:

emit emailAccount(account); 

Cela fonctionne jusqu'à présent. Le problème est que je copie la classe ConfigEmailAccount. Je voudrais éviter cette performance. Donc, mon idée est émette le compte en utilisant 11 sémantique de mouvement de c:

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

I Réécriture les machines à sous et des signaux avec la nouvelle syntaxe:

void foreachEmailAccount(ConfigEmailAccount&& account); 

Unfortunaly, cela ne fonctionne pas. J'ai la prochaine erreur de compilation:

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

Que pourrais-je faire?

exemple minimal vérifiable ici:

#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" 
+0

Je parie qu'il n'y a pas de soutien particulier pour la sémantique de mouvement et des références rvalue dans les signaux de Qt et fentes comme ils ont été conçus en pré-C++ 11 fois. Ainsi, il vaut mieux utiliser la solution native de Qt pour éviter la copie lourde: soit redessiner la classe 'ConfigEmailAccount' pour utiliser [partage implicite] (https://doc.qt.io/qt-5/implicit-sharing.html) soit , si c'est difficile ou impossible, utilisez 'QSharedPointer ' pour les signaux et les slots. – Dmitry

+0

Vous pouvez simplement passer vos objets par des pointeurs. – vahancho

+1

Pourquoi ne pas simplement l'insérer comme 'std :: shared_ptr ' et le transmettre? – rustyx

Répondre