这是我的问题。
我有这样的结构。
struct threadInfo
{
std::condition_variable cv;
std::mutex m;
int priorityLevel;
};
构建我的代码时出现此错误
错误C2280
threadInfo::threadInfo(const threadInfo &)
:尝试 引用已删除的函数PriorityListMutex
根据我的理解,这意味着调用threadInfo
的构造函数并尝试复制mutex
这是不可能的。
我对c ++没有多少经验,即使我有点理解发生了什么,我也不确定如何尝试解决这个问题。任何帮助都会很棒!
以下是使用ThreadInfo
的代码 threadInfo info;
info.priorityLevel = priority;
priorityListMutex.lock();
for (std::list<threadInfo>::iterator it = threadList.begin(); it != threadList.end(); it++)
{
if ((*it).priorityLevel < info.priorityLevel)
{
threadList.insert(it, info);
break;
}
else if (it == threadList.end())
{
threadList.push_back(info);
break;
}
}
priorityListMutex.unlock();
std::unique_lock<std::mutex> lock(info.m);
info.cv.wait(lock);
我猜结构正在那里的某处被复制,但我完全错过了哪里。
答案 0 :(得分:1)
您可以通过避免副本并直接在列表中放置结构来解决您的问题。这确实需要一个自定义构造函数。我已将您的代码示例缩短为仅显示放置部分:
#include <mutex>
#include <condition_variable>
#include <list>
struct threadInfo
{
explicit threadInfo(int prio) : priorityLevel(prio) {}
std::condition_variable cv;
std::mutex m;
int priorityLevel;
};
int main()
{
std::list<threadInfo> threadList;
int priorityLevel = 0;
for (std::list<threadInfo>::iterator it = threadList.begin(); it != threadList.end(); it++)
{
if ((*it).priorityLevel < priorityLevel)
{
threadList.emplace(it, priorityLevel);
break;
}
else if (it == threadList.end())
{
threadList.emplace_back(priorityLevel);
break;
}
}
return 0;
}
答案 1 :(得分:0)
在标准C ++库中,与线程相关的类(如mutex)没有复制构造函数。
当作业涉及两个对象时,例如
package bash
import com.github.kittinunf.fuel.httpGet
import com.github.kittinunf.result.Result
fun main(args: Array<String>) {
val bashImHost = "http://bash.im/"
bashImHost.httpGet().responseString { request, response, result ->
when (result) {
is Result.Failure -> {
println("Some kind of error!")
}
is Result.Success -> {
val htmlBody = result.value
val parsePattern = "<div class=\"text\">(.+)</div>"
val parseRegex = Regex(parsePattern)
val results = parseRegex.findAll(htmlBody)
results.iterator().forEach { resultItem -> println(resultItem.groups[1]?.value) }
}
}
}
}
在第二行,我们尝试创建一个从另一个对象初始化的对象。这使编译器寻找一个复制构造函数,一个专门为此目的而开发的构造函数。
由于具有两个相同的互斥锁副本并不好,因此库不会将此类方法用于与线程相关的类。
通常编译器会在需要时创建默认的复制构造函数,但是当一个类属于这种类型的属性时它不能这样做,所以它会给你和错误。
要解决此问题,您必须明确定义复制构造函数并手动处理。请注意,您应该记住,与mutex和cv等线程相关的内容不应存在于多个副本中。
答案 2 :(得分:0)
显式删除互斥锁的复制构造函数。但是,如果您正在执行的操作是移动而不是复制(例如,您不需要threadInfo对象的旧值),则无法复制互斥锁,而不是使用std::move
移动互斥锁并编写移动你的threadInfo对象的构造函数。
然而,移动构造函数可能导致很难发现bug,所以我不建议这样做。更直接的方法是将“info”对象包装在指针中并使用它。你可以这样做:
auto info = std::make_shared<threadInfo>{};
info->priorityLevel = priority;
priorityListMutex.lock();
for (std::list<std::shared_ptr<threadInfo>>::iterator it = threadList.begin(); it != threadList.end(); it++)
{
if ((*it).priorityLevel < info->priorityLevel)
{
threadList.insert(it, info);
break;
}
else if (it == threadList.end())
{
threadList.push_back(info);
break;
}
}
priorityListMutex.unlock();
std::unique_lock<std::mutex> lock(info.m);
info->cv.wait(lock);
请注意,在这种情况下,我使用的是shared_ptr,这是“最简单”的方法,因为它不会破坏任何东西,但可能不想让你想做,你最想要的是什么do,给出infoList对象的'threadList'对象。在这种情况下,您将其声明为unique_ptr:
auto info = std::make_uniq<threadInfo>{};
and move it into the threadList:
threadList.insert(it, std::move(info));