I am writing a class which uses a thread and I wanted to try the new C++11 std::thread
. I am compiling with Microsoft Visual Studio Pro 2013 v12.0.31101.00 Update 4. The update is from Nov 2014 so is fairly up-to-date. I can use std::thread
for simple uses but in my code below I get compiler errors.
If I comment out the initialization of the thread, as in:
serial(int port) : port_(port) {} //, reader_thread(&serial::reader_thread_func) {}
Then it compiles ok.
How can I fix this?
Here is my code.
serial.hpp:
/* serial port class */
#ifndef SERIAL_
#define SERIAL_
#include <thread>
class serial
{
public:
serial(int port) : port_(port), reader_thread(&serial::reader_thread_func) {}
~serial();
bool open();
bool close();
private:
std::thread reader_thread;
void reader_thread_func();
int port_;
};
#endif // SERIAL_
serial.cpp:
#include <iostream>
#include "serial.hpp"
void serial::reader_thread_func() {
std::cout << "reader thread running with thread id: " << std::this_thread::get_id() << '\n';
}
serial::~serial() {
close();
}
bool serial::open() {
close(); // in case we are already open
std::cout << "opening port " << port_ << '\n';
return true;
}
bool serial::close() {
std::cout << "closing port " << port_ << '\n';
return false;
}
main.cpp to drive:
#include "serial.hpp"
int main() {
serial s(3);
s.open();
s.close();
}
Compiler errors:
1>------ Build started: Project: thread_in_class, Configuration: Debug Win32 ------
1> serial.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1149): error C2064: term does not evaluate to a function taking 0 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 serial::* )(void),void,serial,>,>::_Do_call<,>(std::tuple<>,std::_Arg_idx<>)' 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 serial::* )(void),void,serial,>,>::_Do_call<,>(std::tuple<>,std::_Arg_idx<>)' 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 serial::* )(void),void,serial,>,>::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 serial::* )(void),void,serial,>,>::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 serial::* )(void),void,serial,>,>
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 serial::* )(void),void,serial,>,>
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 serial::* )(void),void,serial,>,>
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 serial::* )(void),void,serial,>,>>(_Thrd_t *,_Target &&)' being compiled
1> with
1> [
1> _Target=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall serial::* )(void),void,serial,>,>
1> ]
1> c:\users\angus\documents\visual studio 2013\projects\thread_in_class\thread_in_class\serial.hpp(10) : see reference to function template instantiation 'std::thread::thread<void(__thiscall serial::* )(void),>(_Fn &&)' being compiled
1> with
1> [
1> _Fn=void (__thiscall serial::* )(void)
1> ]
1> main.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1149): error C2064: term does not evaluate to a function taking 0 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 serial::* )(void),void,serial,>,>::_Do_call<,>(std::tuple<>,std::_Arg_idx<>)' 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 serial::* )(void),void,serial,>,>::_Do_call<,>(std::tuple<>,std::_Arg_idx<>)' 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 serial::* )(void),void,serial,>,>::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 serial::* )(void),void,serial,>,>::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 serial::* )(void),void,serial,>,>
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 serial::* )(void),void,serial,>,>
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 serial::* )(void),void,serial,>,>
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 serial::* )(void),void,serial,>,>>(_Thrd_t *,_Target &&)' being compiled
1> with
1> [
1> _Target=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall serial::* )(void),void,serial,>,>
1> ]
1> c:\users\angus\documents\visual studio 2013\projects\thread_in_class\thread_in_class\serial.hpp(10) : see reference to function template instantiation 'std::thread::thread<void(__thiscall serial::* )(void),>(_Fn &&)' being compiled
1> with
1> [
1> _Fn=void (__thiscall serial::* )(void)
1> ]
1> Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
reader_thread_func
is a class member function. It cannot be called as a standalone function, only on an instance of class serial
. You need to provide an instance of serial
to thread
as the first argument:
reader_thread = std::thread(&serial::reader_thread_func, this);
// ↑↑↑↑
That's what the error "term does not evaluate to a function taking 0 arguments" means - in the context of INVOKE, reader_thread_func
takes one argument: a serial
.