jeudi 5 septembre 2019

Qt One time connection for signal slots with receiver and lambda

Hi I am trying to implement one time connection. It is asked also here but I need to implement it for the syntax (sender, signal, receiver, lambda ) because my lambdas are capturing something from receiver even this is onetime connection I do not want connection to be called after receiver is destroyed. My code so far is as follows :

    template <typename Func1, typename Func2, typename std::enable_if_t<std::is_member_pointer<Func2>::value, int> = 0>
static inline QMetaObject::Connection weakConnect(typename QtPrivate::FunctionPointer<Func1>::Object* sender,
                                                  Func1 signal,
                                                  typename QtPrivate::FunctionPointer<Func2>::Object* receiver,
                                                  Func2 slot)
{
    QMetaObject::Connection conn_normal = QObject::connect(sender, signal, receiver, slot);

    QMetaObject::Connection* conn_delete = new QMetaObject::Connection();

    *conn_delete = QObject::connect(sender, signal, [conn_normal, conn_delete]() {
        QObject::disconnect(conn_normal);
        QObject::disconnect(*conn_delete);
        delete conn_delete;
    });
    return conn_normal;
}

template <typename Func1, typename Func2, typename std::enable_if_t<!std::is_member_pointer<Func2>::value, int> = 0>
static inline QMetaObject::Connection weakConnect(typename QtPrivate::FunctionPointer<Func1>::Object* sender,
                                                  Func1 signal,
                                                  Func2 slot)
{
    QMetaObject::Connection conn_normal = QObject::connect(sender, signal, slot);

    QMetaObject::Connection* conn_delete = new QMetaObject::Connection();

    *conn_delete = QObject::connect(sender, signal, [conn_normal, conn_delete]() {
        QObject::disconnect(conn_normal);
        QObject::disconnect(*conn_delete);
        delete conn_delete;
    });
    return conn_normal;
}

template <typename Func1, typename Func2, typename std::enable_if_t<!std::is_member_pointer<Func2>::value, int> = 0>
static inline QMetaObject::Connection weakConnect(typename QtPrivate::FunctionPointer<Func1>::Object* sender,
                                                  Func1 signal,
                                                  typename QtPrivate::FunctionPointer<Func2>::Object* receiver,
                                                  Func2 slot)
{
    Q_UNUSED(receiver);
    QMetaObject::Connection conn_normal = QObject::connect(sender, signal, slot);

    QMetaObject::Connection* conn_delete = new QMetaObject::Connection();

    *conn_delete = QObject::connect(sender, signal, [conn_normal, conn_delete]() {
        QObject::disconnect(conn_normal);
        QObject::disconnect(*conn_delete);
        delete conn_delete;
    });
    return conn_normal;
}

The problem is with 3rd overload. Because even lambda is not a member function, compilers is defining lambda type as : Class::function::lambda if I create lambda inside Class::function() if I remove is_member check then it becomes redefinition of 1st overload. How can I make this template to work ?

Aucun commentaire:

Enregistrer un commentaire