使用互斥锁和条件变量作为成员时如何修复 "use of deleted function"?
How to fix "use of deleted function" when using mutex and condition variable as member?
我正在做一些多线程练习,无法让这段代码通过编译。我在网上搜索,但到目前为止还不确定原因。
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
class FooBar {
private:
int n;
public:
FooBar(int n) {
this->n = n;
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
printFoo();
}
}
std::mutex foo_mtx;
std::condition_variable foo_cv;
};
void printFoo()
{
cout << "foo";
}
int main ()
{
FooBar foobar(10);
std::thread foo_thread = std::thread(&FooBar::foo, foobar, printFoo);
foo_thread.join();
return 0;
}
如果我不添加互斥量和条件变量,这段代码编译和运行良好。
error: use of deleted function ‘FooBar::FooBar(const FooBar&)’
error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’
error: use of deleted function ‘std::condition_variable::condition_variable(const std::condition_variable&)’
您正在复制 fooBar
。编译器说你不被允许。不允许您这样做,因为无法复制互斥量。
std::thread foo_thread = std::thread(&FooBar::foo, std::ref(foobar), printFoo);
这将使特定的编译器错误消失。如果不构建它,我不能确定没有其他问题。
std::thread foo_thread = std::thread([&foobar]{ foobar.foo(printFoo); });
这是解决同样问题的更理智的方法。 Lambda 通常是比使用基于 INVOKE 的接口更好的计划。
我正在做一些多线程练习,无法让这段代码通过编译。我在网上搜索,但到目前为止还不确定原因。
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
class FooBar {
private:
int n;
public:
FooBar(int n) {
this->n = n;
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
printFoo();
}
}
std::mutex foo_mtx;
std::condition_variable foo_cv;
};
void printFoo()
{
cout << "foo";
}
int main ()
{
FooBar foobar(10);
std::thread foo_thread = std::thread(&FooBar::foo, foobar, printFoo);
foo_thread.join();
return 0;
}
如果我不添加互斥量和条件变量,这段代码编译和运行良好。
error: use of deleted function ‘FooBar::FooBar(const FooBar&)’
error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’
error: use of deleted function ‘std::condition_variable::condition_variable(const std::condition_variable&)’
您正在复制 fooBar
。编译器说你不被允许。不允许您这样做,因为无法复制互斥量。
std::thread foo_thread = std::thread(&FooBar::foo, std::ref(foobar), printFoo);
这将使特定的编译器错误消失。如果不构建它,我不能确定没有其他问题。
std::thread foo_thread = std::thread([&foobar]{ foobar.foo(printFoo); });
这是解决同样问题的更理智的方法。 Lambda 通常是比使用基于 INVOKE 的接口更好的计划。