我一直在尝试对类似执行以下操作(提供以下内容是为了演示编译错误,所以如果你想编译它就可以了,仅此而已)
//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();
}
test.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
const成为事实有关,但后来我不知道该怎样做才能真正实现我想要实际做出的{{1一个成员变量。
编辑:
好吧,我在其他任何评论之前尝试过这些东西,而且它们也没有用,但因为我得到了关于“试试这个”的回复,我将向你展示其他一些不起作用的排列:
使用std :: move(uptr)(相同的错误)
unique_ptr
connect
同样的错误。
更改connect(thread, &QThread::started, [=, uptr = std::move(sensor_ptr) ]()mutable{bar(uptr);};);
以获取右值,同样的错误
更改bar
以获取const值,同样的错误
更改bar
以获取const rvalue,同样的错误
答案 0 :(得分:1)
错误消息告诉您无法复制 lambda 。
可以理解,因为你的lambda是一个以SELECT
ProdName, ManuPartNo, Price, Qty, Supplier
FROM
(SELECT
dbo.TableAllProds.*,
ROW_NUMBER() OVER (PARTITION BY ManuPartNo ORDER BY Price ASC) AS RN
FROM
dbo.TableAllProds) AS t
WHERE
RN = 1
ORDER BY
ManuPartNo
为成员的类 - 而且不可能默认复制这样的类。
std::unique_ptr<T>
接受仿函数,可能会将其存储在内部某处。并且不可能复制你的lambda。
考虑例子:
QObject::connect
答案 1 :(得分:0)
您需要将uptr
移动到栏中,并可能lambda
进入连接。我也不知道 1 连接的目的地是否需要CopyConstructible / CopyAssignable,如果他们这样做,你无能为力。
1 - QT文档没有提及这些事情。
答案 2 :(得分:-1)
std::unique_ptr<>
,只能转发它们,否则它们持有的指针不会是唯一的。
如果您希望将指针的所有权转移给函数,则只能声明unique_ptr参数,如下所示:
void func(std::unique_ptr<foo>& bar); // as a non-const reference
void func2(std::unique_ptr<foo>&& bar); // using the move operator
void func3(std::unique_ptr<boo> bar); // by value, call as func2(std::move(bar));
// call as
func(unique);
func2(unique); // or the more expressive func2(std::move(unique));
func3(std::move(unique));
如果您不想转让所有权,最好将包含的对象作为裸指针或作为参考传递。
void func(foo* bar); // could be const pointer
// call as
func(unique.get());
// or...
void func(foo& bar); // could be const reference
// call as
func(*unique.get());
同样适用于将unique_ptr传递给lambda捕获。