带有 std::thread 的 MVSE12 中的错误 C2248

Posted

技术标签:

【中文标题】带有 std::thread 的 MVSE12 中的错误 C2248【英文标题】:Error C2248 in MVSE12 with std::thread 【发布时间】:2016-06-13 10:07:34 【问题描述】:

大家晚上好!

我正在尝试使用 Microsoft Visual Studio Express 2012 在 C++ 中编写多线程应用程序。

我们的想法是“main”函数调用一个将“永远”运行的线程,其任务是更新对象。

这是主要的:

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <thread>
#include <iostream>//debug only
#include <fstream> //debug only
#include "dataCollectorFTL.h"


int _tmain(int argc, _TCHAR* argv[])


    dataCollectorFTL dataCollector1;

    //Launch thread which will run forever and get the data flows
    dataCollector1.runDataCollector();


    while(true)
        //application running    
    

    return 0;
 

这是类的“.h”

#ifndef DATACOLLECTORFTL_H_INCLUDED
#define DATACOLLECTORFTL_H_INCLUDED


#include <thread>

class dataCollectorFTL 

public:

    void runDataCollector();

    void getData(); 


    //constructor, destructor
    dataCollectorFTL();
    ~dataCollectorFTL();

private:
    HANDLE hProcess;
    std::thread dataCollectorThread;

;

#endif // DATACOLLECTORFTL_H_INCLUDED

最后是“.cpp”

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <thread>
#include "dataCollectorFTL.h"


void dataCollectorFTL::runDataCollector()

    //lauch a non-local thread
    dataCollectorThread = std::thread(&dataCollectorFTL::getData, this);



void dataCollectorFTL::getData()
    //some stuff    



dataCollectorFTL::dataCollectorFTL()
    //some stuff


dataCollectorFTL::~dataCollectorFTL()

    dataCollectorThread.join();

问题是当我运行它时,它给了我这两个错误:

错误 1 ​​错误 C2248:“std::thread::operator =”:无法访问在类“std::thread”c:\users\damien\documents\visual studio 2012\projects\recherche\recherche 中声明的私有成员\datacollectorftl.h 233 1 研究

错误 4 错误 C2248:“std::thread::thread”:无法访问在类“std::thread”c:\users\damien\documents\visual studio 2012\projects\recherche\recherche\ 中声明的私有成员datacollectorftl.h 233 1 研究

为了节省时间,我可以告诉你:

包含在 .h 中不会改变任何内容 runDataCollector 方法的内容不会改变任何东西。即使它是空的,我仍然遇到问题 std::thread dataCollectorThread 可以是公共的也可以是私有的,它不会改变任何东西

如果我不声明为类的成员,我的程序就会崩溃,因为我没有 join() runDataCollector() 中的线程。我不想加入它,getData() 是一个 while(true) 函数,它从另一个软件获取数据。

非常感谢您花时间阅读本文,再次感谢您的帮助。

【问题讨论】:

您正试图在某处复制分配dataCollectorFTL。当然不是在您发布的代码中。 两个错误都突出显示 datacollectorftl.h 中的第 233 行。你能把确切的行贴出来吗?您很难看出编译器在哪里抱怨。 呈现的代码看起来不错; coliru.stacked-crooked.com/a/2c1af3a84792c771。您确定您没有在某处复制父级 dataCollectorFTL 类,这会导致您看到的错误。将其复制和赋值运算符设为私有,错误消息将有助于诊断副本的位置。如果没有,minimal reproducible example 会有所帮助。 感谢大家的帮助。不幸的是,John Burger 的帮助并没有解决问题。恐怕不能完全理解什么是复制分配。第 233 行是 .h 中类的结尾。就代码而言,它是';'我会给你完整的代码。然而它有点乱,为了早期测试我没有把任何东西保密。请原谅这么糟糕的编码。 主要:paste2.org/jsePOO5v.h:paste2.org/gAYAX2CU.cpp:paste2.org/gDBD9e3V 【参考方案1】:

我知道这是前一段时间的问题,但是我遇到了具有相同症状的问题,并且能够解决它,因为我的编译器(VS2012 附带的 VC110)对问题所在有点冗长,所以也许它会帮助某人。

我想使用这个结构:

struct WorkerThreadContext

   std::thread worker;
   ... some other attributes ...

在 std::vector 中。构建导致错误消息:

d:\code\testroom\t2\t2\t2.cpp(16):错误 C2248: 'std::thread::thread' : 无法访问在类 'std::thread' 中声明的私有成员

c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(73) : 参见 'std::thread::thread' 的声明

c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(32) : 参见 'std::thread' 的声明

此诊断发生在编译器生成的函数 WorkerThreadContext::WorkerThreadContext(const WorkerThreadContext &)'

关键部分是最后一句——看来编译器为我的struct生成隐式拷贝构造函数有问题,所以我改成了:

struct WorkerThreadContext

   std::thread worker;
   ... other attributes ...
   WorkerThreadContext() 
   // added explicit copy constructor
   WorkerThreadContext(const WorkerThreadContext&) 
;

并且能够编译代码。

编辑:我差点忘了。编译器有这个问题的原因是,std::thread 对象不能被复制(std::thread::operator=)所以编译器在构造隐式复制构造函数时有问题,因为它不知道如何复制 'std ::线程'对象。这也意味着,如果你把显式的复制构造函数作为我写的那个,你的成员(包括'std::thread'一个变得无效)。您当然可以(并且应该)初始化结构的其余部分,但是 std::thread 将保持未初始化状态,因为您无法复制它。

【讨论】:

【参考方案2】:

当您将函数传递给std::thread 构造函数时,它需要可从文件范围调用。换句话说,如果它是一个成员函数,那么该函数需要是static。你仍然可以传入this - 只需告诉函数期待它。

换句话说:

在类声明中添加以下内容:

private:

   void getData(); // Moved from public!

   static void myGetData(DataCollectorFTL *ftl);

myGetData:

void DataCollectorFTL::myGetData(DataCollectorFTL *ftl) 
    ftl->getData();
 // DataCollectorFLT::myGetData(ftl)

将呼叫改为std::thread()

//lauch a non-local thread
dataCollectorThread = std::thread(&myGetData, this);

【讨论】:

以上是关于带有 std::thread 的 MVSE12 中的错误 C2248的主要内容,如果未能解决你的问题,请参考以下文章

带有 winsock 和 std::thread 的 C++ 多线程服务器

std::thread 使用带有 ref arg 的 lambda 编译失败

在带有标志选项 -m32 的 gcc-8.2.2 上找不到 std::thread。我正在使用 mingw

std::thread 和 std::cin.get

在类构造函数线程中启动 std::thread 是不是安全?

如何使用 std::thread?