使用 std::move 将 std::unique_ptr 作为 qt 信号参数传递

Her*_*man 0 c++ qt smart-pointers unique-ptr qmetaobject

我在Qt工作,我没有提到它,因为我认为这只是C++问题。

我用共享指针解决了这个问题,所以不要给我解决方案。但这是理解的问题,我想了解为什么它不起作用。

我正在尝试以下操作:

测试.h:

#include <QObject>
#include "response.h"
#include <memory>

class Test : public QObject
{
    Q_OBJECT
public:
    explicit Test(QObject *parent = nullptr);

signals:
    void signal(std::unique_ptr<Response> resp);

public slots:

};
Run Code Online (Sandbox Code Playgroud)

测试.cpp:

Test::Test(QObject *parent) : QObject(parent)
{
    std::unique_ptr<Response> response(new Response(5));

    emit signal(std::move(response));
}
Run Code Online (Sandbox Code Playgroud)

Response 班级:

class Response
{
public:
    Response(int data);

private:
     int data;
};
Run Code Online (Sandbox Code Playgroud)

我知道std::unique_ptr不能复制,我std::move在这里使用。但尽管如此,我还是收到了一个错误:

moc_test.cpp:75:85: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Response; _Dp = std::default_delete<Response>]’
         case 0: _t->signal((*reinterpret_cast< std::unique_ptr<Response>(*)>(_a[1]))); break;
Run Code Online (Sandbox Code Playgroud)

在下面的 片段中moc_test.cpp,它是 Qt 元对象系统的产物:

void Test::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void `_a)
{
    if (_c == QMetaObject::InvokeMetaMethod) {
        auto *_t = static_cast<Test *>(_o);
        Q_UNUSED(_t)
        switch (_id) {
//------- !! This line!!
        case 0: _t->signal((*reinterpret_cast< std::unique_ptr<Response>(*)>(_a[1]))); break;
        default: ;
        }
    } else if (_c == QMetaObject::IndexOfMethod) {
        int *result = reinterpret_cast<int *>(_a[0]);
        {
            using _t = void (Test::*)(std::unique_ptr<Response> );
            if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&Test::signal)) {
                *result = 0;
                return;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

花了很多时间,但我无法弄清楚为什么会发生该错误,并且在互联网上找不到任何有用的信息。

Tob*_*ght 5

Qt 信号传递取决于能够复制参数。一个信号可以连接到很多槽,所以传递一个唯一的指针是没有意义的;除了一个收件人之外的所有收件人都将获得空值。

您需要将其转换为共享指针或更改您的方法。