简体   繁体   中英

Error C2248 in MVSE12 with std::thread

Good evening everyone !

I am trying to code a multi-threaded application in C++ with Microsoft Visual Studio Express 2012.

The idea us that the "main" function call a thread which will run "forever", with the task of updating an object.

This is the 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;
} 

This is the ".h" of the class

#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

And finally the ".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();
}

The problem is that when I run it, it gaves me this two errors :

Error 1 error C2248: 'std::thread::operator =' : cannot access private member declared in class 'std::thread' c:\\users\\damien\\documents\\visual studio 2012\\projects\\recherche\\recherche\\datacollectorftl.h 233 1 Recherche

Error 4 error C2248: 'std::thread::thread' : cannot access private member declared in class 'std::thread' c:\\users\\damien\\documents\\visual studio 2012\\projects\\recherche\\recherche\\datacollectorftl.h 233 1 Recherche

To save time, I can tell you that :

  • include in the .h doesn't change anything
  • The content of the runDataCollector methods doesn't change anything. Even if it is empty I still got the problem
  • std::thread dataCollectorThread can be public or private, it doesn't change anything

If I don't declare as a member of the class, I have a crash of the program because I don't join() the thread in runDataCollector(). And I don't want to join it, has getData() is a while(true) function where it gets data from another soft.

Thank you very much for the time you spent reading this, and thank you again for any help.

I understand that it was some time ago, but I bumped into the problem with same symptoms, and was able to solve it since my compilator (VC110 shipped with VS2012) was a little bit more verbose about what's the problem, so maybe it will help somebody.

I wanted to use this struct:

struct WorkerThreadContext
{
   std::thread worker;
   ... some other attributes ...
}

in a std::vector. Build resulted in error message:

d:\\code\\testroom\\t2\\t2\\t2.cpp(16): error C2248: 'std::thread::thread' : cannot access private member declared in class 'std::thread'

c:\\program files (x86)\\microsoft visual studio 11.0\\vc\\include\\thread(73) : see declaration of 'std::thread::thread'

c:\\program files (x86)\\microsoft visual studio 11.0\\vc\\include\\thread(32) : see declaration of 'std::thread'

This diagnostic occurred in the compiler generated function WorkerThreadContext::WorkerThreadContext(const WorkerThreadContext &)'

Key part is the last sentence - it seems that compiler has a problem to generate implicit copy constructor for my struct, so I changed it to:

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

and was able to compile the code.

Edit: I almost forget. The reason why the compiler has a problem with this is, that std::thread objects cannot be copied ( std::thread::operator= ) so the compiler has a problem to construct implicit copy constructor, because it doesn't know how to copy the 'std::thread' object. Which also means, that if you put there explicit copy constructor as the one I wrote, your members (including the 'std::thread' one become invalid). You may (and you should) of course initialize the rest of the struct, however std::thread will remain uninitialized, because you cannot copy it.

When you pass a function in to the std::thread constructor, it needs to be callable from file-scope. In other words, if it's a member function, that function needs to be static . You can still pass in this - just tell the function to expect it.

In other words:

  • Add the following to the class declaration:

     private: void getData(); // Moved from public! static void myGetData(DataCollectorFTL *ftl); 
  • Write myGetData :

     void DataCollectorFTL::myGetData(DataCollectorFTL *ftl) { ftl->getData(); } // DataCollectorFLT::myGetData(ftl) 
  • Change the call to std::thread()

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM