错误 C2280:'std::thread::thread(const std::thread &)':尝试引用已删除的函数
Error C2280: 'std::thread::thread(const std::thread &)' : attempting to reference a deleted function
我在创建使用C++11标准线程的VC++静态库时遇到问题。
我目前有两个类,我可以在开始的类(最后声明的)上声明并稍后定义一个线程。在这个阶段,代码只是一个套接字侦听器,然后创建另一个类的对象来处理接受的每个客户端。这些子对象应该创建并行数据捕获、编码和传输所需的线程。
问题是:如果我在我的另一个类上声明了一个std::线程,即使和我在开始类上一样,不管怎样,我在构建error C2280: 'std::thread::thread(const std::thread &)' : attempting to reference a deleted function [...]vcincludefunctional 1124 1
时都会收到这个错误
我能够解决这个错误的唯一方法是简单地不在后一个类中声明std::thread
对象,根据我希望它做的,这是不可能的…
我使用的是VS2013,我的来源是:
stdafx.h
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <thread>
#include <iostream>
#include <vector>
StreamServer.h
#pragma once
#define DEFAULT_BUFLEN 65535
#define DEFAULT_PORT "5649"
class StreamServerClient
{
public:
bool* terminate;
//std::thread client; //If I comment this line out, it builds just fine.
void DoNothing();
StreamServerClient(SOCKET clientSock, bool* ptTerm);
StreamServerClient();
~StreamServerClient();
};
class StreamServer
{
public:
bool terminate;
std::thread Listener;
std::vector<StreamServerClient> clients;
void CreateClient(SOCKET, bool*);
void Listen();
StreamServer();
~StreamServer();
};
StreamServer.cpp
#include "stdafx.h"
#include "StreamServer.h"
StreamServerClient::StreamServerClient(SOCKET clientSock, bool* ptTerm)
{
terminate = ptTerm;
//client = std::thread(&StreamServerClient::DoNothing, this); //Same thing as the declaration
}
StreamServerClient::StreamServerClient()
{
*terminate = false;
//client = std::thread(&StreamServerClient::DoNothing, this); //Same thing as the declaration
}
void StreamServerClient::DoNothing()
{
}
StreamServerClient::~StreamServerClient()
{
}
void StreamServer::Listen()
{
{...}
do {
clients.push_back(StreamServerClient::StreamServerClient(accept(listenSock, NULL, NULL), &terminate));
std::cout << "accepted a client!" << std::endl;
} while (!terminate);
}
StreamServer::StreamServer()
{
terminate = false;
Listener = std::thread(&StreamServer::Listen, this);
Listener.detach();
}
StreamServer::~StreamServer()
{
}
std::thread
类型的对象。您最好只初始化成员初始值设定项列表中的对象:
class StreamServerClient
{
public:
bool* terminate;
std::thread client;
void DoNothing();
StreamServerClient(SOCKET clientSock, bool* ptTerm);
StreamServerClient(StreamServerClient&& other);
~StreamServerClient();
};
StreamServerClient::StreamServerClient(SOCKET clientSock, bool* ptTerm)
: terminate(ptTerm)
, client(std::thread(&StreamServerClient::DoNothing, this)) {
}
StreamServerClient::StreamServerClient(StreamServerClient&& other)
: terminate(other.terminate)
, client(std::move(other.client)) {
}
我提交了默认构造函数(请注意,您的版本不起作用,因为它试图为取消引用未初始化指针的结果分配一个值),而是添加了一个移动构造函数:当推回到std::vector<...>
时,当提供看起来像临时的东西时,将调用此构造函数(即,是临时的或看起来像临时的东西,例如,使用std::move()
)。
std::thread
对象不可复制。当这条线被调用时:
clients.push_back(StreamServerClient::StreamServerClient(accept(listenSock, NULL, NULL), &terminate));
您创建的StreamServerClient
对象需要添加到clients
向量中,但唯一的方法是复制它,因为您的StreamServer
对象没有定义移动构造函数。生成了StreamServerClient
的默认复制构造函数,而C++11中的默认复制构造器所做的是,它调用所有数据成员的复制构造函数。
在这种情况下,它正在调用已删除的std::thread
数据成员的复制构造函数。
std::thread
s无法复制的原因是std::thread
对象对应于执行的线程。IMO,你应该重构你的代码。你可以为StreamServerClient
拼凑一个移动构造函数,但我认为有更干净的解决方案,例如,用指向std::thread
的指针替换std::thread
,并用一个完全独立的调用初始化线程。
编辑:一般来说,在对象的构造函数中分支一个新线程是不明智的,因为这是一个过于精细的操作。(它可能会失败,然后你必须处理异常等)尽管C++纯粹主义者可能会不同意我的观点。
编辑:有愚蠢的术语。
- 在std::thread中,joinable()然后join()线程安全吗
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 分离一个静态常量 std::thread?
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 如何从 std::thread 返回值
- 将 std::thread by 值推送到列表中
- 转发变量参数列表以模拟 std::thread
- 嵌入式设备 -> std::thread -> FreeRTOS?
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- std::thread 增加 DLL 引用计数,从而防止卸载 DLL
- 如何防止 std::thread 在 QT 中冻结 GUI?
- 对带有唯一指针的 std::thread 使用类成员函数时出现编译错误
- 为什么参数在构造 std::thread 时移动两次
- std::thread::_Invoker 使用线程编程时出错
- 在线程 A 中创建一个 std::thread 对象,在线程 B 中连接
- 为什么编译器抱怨 std::thread 参数在转换为右值后必须是可调用的?
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- 使用 std::thread & std::bind 在成员函数中启动线程
- 从gcc 5.4升级至gcc 6.3 std::thread std:ref issue