Why is this not compiling? (RValue as thread CTOR arguments) - multithreading

Hello here is a test code I wrote on MSVC12.
Could someone tell me why the std::move when I pass parameters to the thread are not converting the variabes to RValue refs??
And what I should do.
Thank you!
///some arbitrary long task
std::string DumpFile(std::string path){
std::this_thread::sleep_for(std::chrono::seconds(10));
return path;
}
void run_promise(std::promise<std::string> &&_prom, std::string &&_path){
try {
std::string val = DumpFile(std::move(_path));
_prom.set_value(val);
}
catch (...) {
_prom.set_exception(std::current_exception());
}
}
std::future<std::string> ADumpFile(std::string && path) {
std::promise<std::string> prms;
std::future<std::string> fut = prms.get_future();
std::thread th(run_promise, std::move(prms), std::move(path));
th.detach();
return fut;
}
int main(int argc, char* argv []){
auto fut = ADumpFile("toto");
while (fut.wait_for(std::chrono::seconds(1))!=std::future_status::ready){
std::cout << "waiting\n";
}
auto res = fut.get();
getchar();
return 0;
}
The error I get is :
Error 1 error C2664: 'void (std::promise<std::string> &&,std::string &&)' : cannot convert argument 2 from 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' to 'std::string &&' C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 1149 1 demo11
Error 2 error C2664: 'void (std::promise<std::string> &&,std::string &&)' : cannot convert argument 1 from 'std::promise<std::string>' to 'std::promise<std::string> &&' C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 1149 1 demo11
Although, if I call run_promise(std::move(prom),std::move(path)) I have no problem.
Is this an issue related to passing the rvalue arguments through the thread CTOR?

Well, this problem was reported for VC11 http://connect.microsoft.com/VisualStudio/feedback/details/737812 and seems MS didn't address in VC12.

Related

circular buffer for opencv cv::Mat

I use this example for circular buffering.
To test test I created next three functions:
void cnt(ScreenStreamer &SS, cv::Mat & img)
{
CVUtils::Image m_img;
SS >> m_img;
img = m_img.matRef();
cv::imshow("",img);
cv::waitKey();
}
void snd1(circ_buffer<cv::Mat > & CM, cv::Mat & M)
{
CM.send(M);
}
void rcv1(circ_buffer<cv::Mat > & CV, cv::Mat & M)
{
M = CV.receive();
}
And then run it in main function:
int main()
{
ScreenStreamer stream;
CVUtils::Image m_img;
cv::Mat bufImg;
cv::Mat inpImg;
int key = 0;
circ_buffer<cv::Mat > F1;
F1.set_capacity(50);
std::thread m1( snd1, F1, &inpImg );
std::thread m2( rcv1, F1, &bufImg );
std::thread m3( cnt, stream, &inpImg);
m1.join();
m2.join();
m3.join();
return 0;
}
Unfortunatelly I get this error
Error C2664 'std::tuple<void (__cdecl *)(circ_buffer<cv::Mat> &,cv::Mat &),circ_buffer<cv::Mat>,cv::Mat *>::tuple(std::tuple<void (__cdecl *)(circ_buffer<cv::Mat> &,cv::Mat &),circ_buffer<cv::Mat>,cv::Mat *> &&)': cannot convert argument 1 from 'void (__cdecl &)(circ_buffer<cv::Mat> &,cv::Mat &)' to 'std::allocator_arg_t' CVUtilsExperimental C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\memory 1630
Does it come from template implementation or from function implementations?
What to google to solve it?
All your functions take parameters by reference, you need to use std::ref wrapper class to pass them to thread constructor:
The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref). thread reference
so rewrite as follows
std::thread m1( snd1, ref(F1), ref(inpImg) );
std::thread m2( rcv1, ref(F1), ref(bufImg) );
std::thread m3( cnt, ref(stream), ref(inpImg) );

static constexpr member in-class initialization

Could anyone help me find out what is wrong with in-class initialization of
static constexpr member varaible like in the code below ?
Using Visual Studio 2013
struct hg {
public:
static constexpr float asd = 9.0f;
};
int main() {
return 0;
}
The above code gives the following errors :
Error 1
error C2144: syntax error : 'float' should be preceded by ';'
Error 2
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

error when use std::thread in Class

I tried to use std::thread in Visual Studio 2013. It works all right like this.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <chrono> // std::chrono::seconds
#include <iostream> // std::cout
#include <thread> // std::thread, std::this_thread::sleep_for
#include <vector>
void thread_task(int n) {
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "hello thread "
<< std::this_thread::get_id()
<< " paused " << n << " seconds" << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<std::thread> threads;
std::cout << "Spawning 5 threads...\n";
for (int i = 0; i < 5; i++) {
threads.emplace_back( std::thread(thread_task, i + 1));
}
std::cout << "Done spawning threads! Now wait for them to join\n";
for (auto& t : threads) {
t.join();
}
std::cout << "All threads joined.\n";
return 0;
}
but when I tried to make thread in a Class, I met some compiling errors.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <chrono> // std::chrono::seconds
#include <iostream> // std::cout
#include <thread> // std::thread, std::this_thread::sleep_for
#include <vector>
class MyClass
{
public:
MyClass();
void thread_task(int n);
~MyClass();
private:
};
MyClass::MyClass()
{
std::vector<std::thread> threads;
std::cout << "Spawning 5 threads...\n";
for (int i = 0; i < 5; i++) {
threads.emplace_back(std::thread(&MyClass::thread_task, i + 1));
}
std::cout << "Done spawning threads! Now wait for them to join\n";
for (auto& t : threads) {
t.join();
}
std::cout << "All threads joined.\n";
}
void MyClass::thread_task(int n) {
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "hello thread "
<< std::this_thread::get_id()
<< " paused " << n << " seconds" << std::endl;
}
MyClass::~MyClass(){}
int _tmain(int argc, _TCHAR* argv[])
{
MyClass test();
return 0;
}
The error messages are copied below.
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1149): error C2064: term does not evaluate to a function taking 1 arguments
1> class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>::_Do_call<,0>(std::tuple<>,std::_Arg_idx<0>)' being compiled
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>::_Do_call<,0>(std::tuple<>,std::_Arg_idx<0>)' being compiled
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\thr\xthread(195) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>::operator ()<>(void)' being compiled
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\thr\xthread(195) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>::operator ()<>(void)' being compiled
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\thr\xthread(192) : while compiling class template member function 'unsigned int std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *)'
1> with
1> [
1> _Target=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\thr\xthread(187) : see reference to function template instantiation 'unsigned int std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *)' being compiled
1> with
1> [
1> _Target=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\thr\xthread(205) : see reference to class template instantiation 'std::_LaunchPad<_Target>' being compiled
1> with
1> [
1> _Target=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\thread(49) : see reference to function template instantiation 'void std::_Launch<std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>>(_Thrd_t *,_Target &&)' being compiled
1> with
1> [
1> _Target=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall MyClass::* )(int),void,MyClass,int>,int>
1> ]
1> d:\projects\consoleapplication2\consoleapplication2\consoleapplication2.cpp(29) : see reference to function template instantiation 'std::thread::thread<void(__thiscall MyClass::* )(int),int>(_Fn &&,int &&)' being compiled
1> with
1> [
1> _Fn=void (__thiscall MyClass::* )(int)
1> ]
1>
What cause the problem?
Thanks #malchemist, when add this solve the problem. But it makes me confused this piece of codecode error still got some compiling errors even written just like the answer shows.
Can anyone help me? Thanks a lot.
You have to specify an object to call function inside new thread. Try this:
threads.emplace_back(std::thread(&MyClass::thread_task,this, i + 1));

VC warning 4365 seems to be inconsistent

My question is: why does VC emit warning 4365 for only one of the commented lines below, and not the other?
#pragma warning(1: 4365)
void test1(const unsigned short) {}
unsigned short test2() { return 0; }
int main()
{
const unsigned short a = 0;
const unsigned short b = 0;
test1(a + b); // This line gives no warning
test1(test2() + b); // This line gives C4365
return 0;
}
Tested under VS2010 and VS2012 Express.
For reference, the full warning text is this:
warning C4365: 'argument' : conversion from 'int' to 'const unsigned short', signed/unsigned mismatch
Using Clang 3.3 (through Clang-Win32 and ClangVSx), no warnings are reported in this code (except of course the unknown pragma).

can't get length of string in vc++

I want to retrive files with extension of .jpg from directory in vc++ 08. I'm not much comfortable with pointers so I got error when I try to get length of string in following code. Can anyone help me out??
Here is my code..
#include<iostream>
#include <string>
#pragma warning( disable : 4996 )
#include "dirent.h"
#pragma warning( default : 4996 )
using namespace std;
int main(int argc, char *argv[])
{
if(argc != 2)
{
cout<<"Usage: "<<argv[0]<<" <Directory name>"<<endl;
return -1;
}
DIR *dir;
dir = opendir (argv[1]);
if (dir != NULL)
{
string name; string ext = ".jpg"; int len;
cout<<"Directory Listing for "<<argv[1]<<" : "<<endl;
struct dirent *ent;
while ((ent = readdir (dir)) != NULL)
{
name = ent->d_name;
len = name.length; // here i got error...
name = name.substr(0, len-4);
if(_stricmp(name.c_str(), ext.c_str()) == 0)
{
cout<<ent->d_name<<endl;
}
else
{
cout<<"No JPG file"<<endl;
}
}
}
else
{
cout<<"Invalid Directory name"<<endl;
return -1;
}
return 0;
}
And error is
example.cpp(29) : error C3867: 'std::basic_string<_Elem,_Traits,_Ax>::length': function call missing argument list; use '&std::basic_string<_Elem,_Traits,_Ax>::length' to create a pointer to member
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1>\example.cpp(29) : error C2440: '=' : cannot convert from 'unsigned int (__thiscall std::basic_string<_Elem,_Traits,_Ax>::* )(void) const' to 'int'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> There is no context in which this conversion is possible
Thanks in advance...
len = name.length();
// ^^
length is a member function, not a member variable. You need to call that function.

Resources