【发布时间】:2017-08-08 14:11:44
【问题描述】:
我一直在尝试做一些类似的事情(提供以下内容是为了演示编译错误,所以如果你想编译它你可以,仅此而已)
//main.cpp
#include <QApplication>
#include "test.h"
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Test t;
std::string s = "hi ";
std::unique_ptr<std::string> sptr = std::make_unique<std::string>(s);
t.foo(sptr);
return a.exec();
}
测试.h
//test.h
#ifndef TEST_H
#define TEST_H
#include <QObject>
#include <QThread>
#include <string>
#include <QApplication>
#include <memory>
class Test : public QObject{
Q_OBJECT
public:
void foo(std::unique_ptr<std::string> t_ptr);
void bar(std::unique_ptr<std::string> t_ptr);
};
#endif //TEST_H
test.cpp
//test.cpp
#include "test.h"
#include <iostream>
void Test::foo(std::unique_ptr<std::string> t_ptr){
QThread * thread = new QThread(this);
moveToThread(thread);
auto lambda = [=, uptr = std::move(t_ptr) ]()mutable{bar(uptr);};
connect(thread, &QThread::started, lambda);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void Test::bar(std::unique_ptr<std::string> t_ptr){
t_ptr->append("hello");
std::cout << *t_ptr << std::endl;
moveToThread(QApplication::instance()->thread());
}
但无论我做什么,我似乎都无法编译,我最终得到的只是这个:
error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = std::__cxx11::basic_string<char>; _Dp = std::default_delete<std::__cxx11::basic_string<char> >]'
auto lambda = [=, uptr = std::move(t_ptr) ]()mutable{bar(uptr);};
^
note: declared here
unique_ptr(const unique_ptr&) = delete;
或者除了那个错误之外,还有这个错误:
In member function 'void Test::foo(std::unique_ptr<T>)':
error: use of deleted function 'Test::foo(std::unique_ptr<std::__cxx11::basic_string<char> >)::<lambda()>::<lambda>(const Test::foo(std::unique_ptr<std::__cxx11::basic_string<char> >)::<lambda()>&)'
connect(thread, &QThread::started, lambda);
更改为mutable 也会导致相同的错误,显然我已经使用了here 找到的答案。
我确定这与 lambda 捕获使unique_ptr 成为常量这一事实有关,但是我不确定如何才能真正完成我想要实现的目标,而实际上却使unique_ptr 成为成员多变的。
编辑:
好的,我在其他人评论之前尝试了这些东西,但它们也没有奏效,但因为我收到了关于“试试这个”的回复,所以我将向您展示其他一些不起作用的排列:
使用 std::move(uptr)(同样的错误)
在connect中创建Lambda
connect(thread, &QThread::started, [=, uptr = std::move(sensor_ptr) ]()mutable{bar(uptr);};);
同样的错误。
将bar改成右值,同样的错误
更改bar 为 const 值,同样的错误
将bar 改为 const rvalue,同样的错误
【问题讨论】:
-
bar(std::move(uptr));在 lambda 中。如果您仍然看到错误,请发布minimal reproducible example。您可能还需要std::move(lambda);这里 -connect(thread, &QThread::started, lambda);,但我不确定connect是如何工作的。 -
@Praetorian qt 的东西不相关吗?为何如此?这也是非常小的......
-
@Praetorian,我也使用了 std::move 并没有解决任何问题,它仍然认为我正在使用已删除的 const unique_ptr 构造函数...
-
示例不完整,其他人无法编译。 Qt 的东西可能是相关的,但第一步是把它拿出来,看看你是否还能重现这个问题。如果不能,则一次将其添加回一件事。
-
@Praetorian Ok 更新了可验证的示例,同样的错误。
标签: c++ multithreading qt lambda c++14