I run into problem with rvalue references in MSVC 2012.
#include <thread>
#include <string>
#include <future>
void foo(std::promise<std::string> &&prms) { /* some code */ }
int main() {
std::promise<std::string> prms;
// std::future<std::string> ftr = prms.get_future();
std::thread th(&foo, std::move(prms));
// some other code
}
Compiler says: error C2664: 'void (std::promise<_Ty> &&)' : cannot convert parameter 1 from 'std::promise<_Ty>' to 'std::promise<_Ty> &&'
Is there my mistake (then how to fix it) or compiler issue (then I'd like to know origin of such behaviour)?
This is a known issue in the Visual C++ 2012 implementation of std::thread. See the following bug on Microsoft Connect:
std::thread constructor doesn't handle movable object
The response to that bug states:
We attempted to fix this during VC11's development, but it exploded horribly and we had to revert the change. As it turns out, std::thread can't be powered by bind(), because thread needs to move its arguments, and bind() is forbidden from doing so (since bound functors should be repeatedly invokable, without their bound arguments being moved-from). So we'll need to reimplement std::thread's ctor to avoid using bind().
Related
The following code in a Visual Studio Professional 2019 project (version 16.3.6) produces a warning:
#include <thread>
#include <future>
class Foo {
public:
mutable std::recursive_mutex _writingMutex;
std::recursive_mutex& writingMutex() const { return _writingMutex; }
};
int main()
{
Foo a;
std::lock_guard<std::recursive_mutex> lock(a.writingMutex()); // produces C26110
std::lock_guard<std::recursive_mutex> lock2(a._writingMutex); // no warning
}
The first lock produces the warning C26110:
Warning C26110 Caller failing to hold lock 'lock' before calling function 'std::lock_guard::~lock_guard'
Why is this so? Does passing the mutex as reference not work?
Based on the compilation result of Alan and the comment of rustyx, I will answer my own question:
This is likely to be a code analysis bug in Visual Studio. Looks like C26110 can't recognize a mutex via a reference. The issue was reported here and I added my minimal example as comment there. The issue persists in the most recent version 16.3.7 as well
Using Microsoft Visual C++ 2013 (12.0), I am encountering compile-time errors when using a lambda in a constructor in a variadic template. I have managed to boil it down as shown below (see the lines with the error comments). It appears to be a bug in 12.0 that is not present in 14.0. I haven't tried other versions. Is there any documentation on this bug, perhaps in the form of a release note that clarifies the conditions under which this bug occurs and which states that it has been explicitly fixed?
#include <functional>
// a simple method that can take a lambda
void MyFunction(const std::function<void()>& f) {}
// a simple class that can take a lambda
class MyClass
{
public:
MyClass(const std::function<void()>& f) {}
};
// non-templated test
void test1()
{
MyFunction([] {}); // OK
MyClass([] {}); // OK
MyClass o([] {}); // OK
}
// non-variadic template test
template<typename T>
void test2()
{
MyFunction([] {}); // OK
MyClass([] {}); // OK
MyClass o([] {}); // OK
}
// variadic template test
template<typename... T>
void test3()
{
MyFunction([] {}); // OK
MyClass([] {}); // OK
MyClass a([] {}); // error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
// error C2440: 'initializing' : cannot convert from 'test3::<lambda_12595f14a5437138aca1906ad0f32cb0>' to 'int'
MyClass b(([] {})); // putting the lambda in an extra () seems to fix the problem
}
// a function using the templates above must be present
int main()
{
test1();
test2<int>();
test3<int, int, int>();
return 1;
}
Edit/Update: MSVC 2013 compiler seem to have this bug, latest versions fixed that. GCC and clang compilers don't show any error.
I can't say is that bug or not, back days Microsoft was not so eager to latest C++ standards, it was two steps behind GCC and CLang, and it's not a surprise to know that no-one implement a whole standard in one compiler update. Some stuff from std library may be partially implemented, for example Visual Studio usually implements new features under std::experimental namespace (filesystem for VS2013), but something like compiler lexemes can't be added that way.
For common information about standard compatibility I suggest to use compiler support article https://en.cppreference.com/w/cpp/compiler_support/11 (MSVC means _MSC_VER definition) and
https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance more for detailed information about Visual Studio. Here https://en.wikipedia.org/wiki/Microsoft_Visual_C++#Internal_version_numbering you can find _MSC_VER version along with related Visual Studio version, source is https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros.
Based on those articles I believe that your problem lays in between "Variadic templates" and "Lambda expression" both are fully supported from Visual Studio 19.0, searching _MSC_VER 1900 in wiki that means Visual Studio 2015 (Update 2, if to be precise according to Microsoft article).
vs2015 can be compiled normally, because vs2015 can fully support the c++11 standard, you can consider upgrading your vs
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);
This question already has answers here:
Start thread with member function
(5 answers)
Closed 7 years ago.
Good afternoon,
I've been attempting to create a handful of threads to execute an update loop on some data, but when I attempt to call std::thread newThread(updateLoop), I get a generic compiler error for:
"No instance of constructor 'std::thread::thread' matches the argument list,"
and a MS VC++ 2015 error C3867:
"'projectileHandeler::updateLoop': non-standard syntax; use '&' to create a pointer to member"
When I attempt to follow the recommendation in C3867, changing the threading call to std::thread newThread(&updateLoop) the compiler throws MS VC++ C2276:
"'&': illegal operation on bound member function expression."
After reading the compiler error resources and trying variations such as std::thread newThread(this->updateLoop), std::thread newThread(*updateLoop), and std::thread newThread(*&updateLoop) [I was getting desperate then... I knew that last one wasn't going to work... ], I still get various errors relating to either an improper reference or my call the std::thread not matching the any overloads.
Could anyone please shed some light on my mistakes, please?
Of course, the code:
ProjectHandeler.cpp:
NB: The standard library thread and vector headers are included in stdafx.h
#include "stdafx.h"
#include "DataTypes.h"
#include "ProjectHandeler.h"
projectileHandeler::projectileHandeler(projectile* inputList[], int inputCount) {
for (int i = 0; i < inputCount; i++) {
projectileList.push_back(*inputList[i]);
}
//Create 1 thread for each 10 projectiles.
for (unsigned int i = 0; i < projectileList.size(); i++) {
std::thread thread(updateLoop);
thread.detach();
}
}
void projectileHandeler::updateLoop() {
//Do stuff
}
ProjectHandeler.h:
#pragma once
#ifndef PROJECTILE_H
#define PROJECTILE_H
#include "stdafx.h"
#include "DataTypes.h"
#endif
class projectileHandeler {
private:
std::vector<projectile> projectileList;
void updateLoop();
public:
projectileHandeler(projectile* inputList[], int inputCount);
~projectileHandeler();
projectile* getProjectilePointerFromId(unsigned int id);
//Make the NPC and Player handeler friend classes
};
Solution found... Although I still can't make the original version work, studying the post suggested by Niall had an obscure mention to using lambdas to preform the threading, which bypasses the need for member function references.
Therefore std::thread newThread(updateLoop); becomes std::thread([this] { updateLoop(); });
The later version also has the benefit of starting the thread anonymously,allowing the loop to execute with out having to rename anything.
That said, I would still appreciate an explanation to why the original code doesn't compile. After reading through it, I couldn't find an answer for the specific case here in the suggested duplicate post.
I'm following some tutorials by Bartosz Milewski here which I find very useful.
However, as the author uses the just::thread implementation of the C++11 threading standard (which I don't yet have), I have decided to go with boost threads for now as the author of the tutorial says its trivial to do so. This seems to be the case for the first three tutorials in the series but I bumped into some problems with the fourth. Here is my code:
#include <iostream>
#include <cassert>
#include <boost\thread.hpp>
#include <boost\thread\future.hpp>
void thFun(boost::promise<std::string> & prms)
{
std::string str("Hi from future!");
prms.set_value(str);
}
int main()
{
boost::promise<std::string> prms;
boost::unique_future<std::string> fut = prms.get_future();
boost::thread th(&thFun, std::move(prms)); // error C2248: 'boost::promise<R>::promise' : cannot access private member declared in class 'boost::promise<R>'
std::cout << "Hi from main!";
std::string str = fut.get();
std::cout << str << std::endl;
th.join();
return 0;
}
The following line seems to raise an issue that I don't understand:
boost::thread th(&thFun, std::move(prms));
where the compiler complains:
error C2248: 'boost::promise::promise' : cannot access private
member declared in class 'boost::promise'
Can anyone suggest what the problem might be?
thanks in advance!
boost::thread uses boost::bind to handle a thread function with additional arguments, which requires that they are copyable. You could pass the promise by pointer or reference (using e.g. boost::ref), but that requires that the object outlives the thread. In this example it is OK, but for a detached thread, or one which outlives the function that started it, this would prevent the use of boost::promise objects on the stack.