2017-03-04 3 views
1

Ich habe ein Projekt mit QT 5.7 & Visual Studio 2015, die einen Compiler-Fehler über Deduktionsregeln emittiert. Ich bin ein wenig Anfänger, was die Deduktionsregeln betrifft, also würde ich gerne sehen, ob mir jemand zeigen könnte, wie man damit umgeht und auch erklärt, was passiert, wenn die Funktionssignatur-Übereinstimmung geht.Vorlage Argument Abzug stimmt nicht mit QT Lambda

Ich versuche, eine Vorlage basierten Smart Connector zu verwenden, um die Signale und Slots in meinem QT-Projekt zu verwalten. Ich habe die Inspiration für diesen Ansatz zur Signal/Slot-Verwaltung von this Q&A in Stack Overflow erhalten. Der Template-Code, die angeblich, um automatisch das Signal/Slots zu verwalten ist wie folgt:

//! see https://stackoverflow.com/questions/26553029/ 
//! how-to-disconnect-a-lambda-function-without-storing-connection. 
using ListenToken = std::shared_ptr<void>; 

struct Disconnecter { 
    QMetaObject::Connection mConnection; 
    explicit Disconnecter(QMetaObject::Connection&& conn) 
     : mConnection(std::move(conn)) 
    {} 

    ~Disconnecter() { 
     QObject::disconnect(mConnection); 
    } 
}; 

template<class F, class T, class M> 
ListenToken QtConnect(T* source, M* method, F&& f) { 
    return std::make_shared<Disconnecter>(
     QObject::connect(source, method, std::forward<F>(f)) 
    ); 
} 

using SignalSlotInfo = std::vector<ListenToken>; 

In meinem Hauptfenster Klasse Ich habe ein SignalSlotInfo Mitglied, das ich Spur des Signals/Slots zu halten verwenden, so dass diese automatisch trennen Wenn die Anwendung eines bestimmten Benutzeroberflächenereignisses geschlossen wird.

Das fragliche QT-Objekt, das ich versuchen möchte, ist der QSerialPort. Ich versuche, das QSerialPort des ‚Bytes geschrieben‘ Signal (geerbt von seinem QIODevice Elternteil) zu einem Schlitz in einem Lambda zu verbinden, aber es funktioniert nicht mit dem folgenden Fehler kompilieren:

1>mainwindow.cpp(1246): error C2672: 'QtConnect': no matching overloaded function found 
1>mainwindow.cpp(1246): error C2784: 'ListenToken QtConnect(T *,M *,F &&)': could not deduce template argument for 'M *' from 'void (__cdecl QIODevice::*)(qint64)' 
1> c:\users\johnc\main\app739\app739\mainwindow.h(58): note: see declaration of 'QtConnect' 

Wenn ich versuche, dies zu tun, ohne die Verwendung von Lambda-Ausdrücke (mit der QT-Anrufe verbinden), es funktioniert per ....

// Connect Tx/Rx handlers 
connect(mPort.get(), &QSerialPort::bytesWritten, this, &MainWindow::processTx); 

jedoch die QtConnect Vorlage in mainwindow.cpp Aufruf wie folgt:

// Connect Tx/Rx handlers 
QtConnect(mPort.get(), &QSerialPort::bytesWritten, [&](qint64 bytes) { 
    ... 
}); 

Ergebnisse in den oben angegebenen Fehlern. mPort ist ein Zeiger std::unique_ptr<QSerialPort>

Das bytesWritten Signal von QSerialPort der übergeordneten Klasse geerbt wird QIODevice und hat die Unterschrift void bytesWritten(qint64 bytes)

Antwort

1

ersetzen M* von M:

template<class F, class T, class M> 
ListenToken QtConnect(T* source, M method, F&& f) { 
    return std::make_shared<Disconnecter>(
     QObject::connect(source, method, std::forward<F>(f)) 
    ); 
} 

Der Grund dafür ist, dass, wenn Sie verlassen M* Der Compiler wird versuchen, die Vorlage aufzulösen, indem M* auf void (QIODevice::*)(qint64) festgelegt wird. Jedoch ist void (QIODevice::*)(qint64) ein pointer-to-member, kein pointer und M* ist explizit ein pointer. Dieser Widerspruch führt dazu, dass der Compiler die Vorlage nicht auflösen kann.

Verwandte Themen