Вычисление аргумента шаблона не совпадает с лямбда QT

У меня есть проект с QT 5.7 & Visual Studio 2015, которая выдает ошибку компилятора о правилах удержания. Я немного новичок в том, что касается правил дедукции, поэтому я хотел бы посмотреть, может ли кто-нибудь показать мне, как обойти это, а также объяснить, что происходит с сопоставлением сигнатур функций.

Я пытаюсь использовать умный соединитель на основе шаблонов для управления сигналами и слотами в моем проекте QT. Я получил вдохновение для этого подхода к управлению сигналами / слотами от этот вопрос& в переполнении стека. Код шаблона, который должен автоматически управлять сигналом / слотами, выглядит следующим образом:

//! 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>;

В моем классе главного окна у меня есть SignalSlotInfo член, который я использую для отслеживания сигнала / слотов, чтобы они могли автоматически отключаться при закрытии приложения какого-либо события пользовательского интерфейса.

Рассматриваемый объект QT, который я пытаюсь подключить, — это QSerialPort. Я пытаюсь подключить сигнал QSerialPort «записано в байтах» (унаследованный от его QIODevice parent) в слот в лямбде, но он не может скомпилировать следующую ошибку:

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'

Если я попытаюсь сделать это без использования лямбда-выражений (используя вызовы QT-соединения), то это будет нормально работать ….

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

Однако, вызывая шаблон QtConnect в mainwindow.cpp следующим образом:

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

Результаты в ошибках, указанных выше. mPort это указатель std::unique_ptr<QSerialPort>

bytesWritten сигнал наследуется от родительского класса QSerialPort QIODevice и имеет подпись void bytesWritten(qint64 bytes)

1

Решение

замещать M* от 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))
);
}

Причина этого в том, что если вы уйдете M* компилятор попытается разрешить шаблон, имея M* установлен в void (QIODevice::*)(qint64), тем не мение void (QIODevice::*)(qint64) это pointer-to-memberне pointer а также M* явно pointer, Это противоречие делает компилятор неспособным разрешить шаблон.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector