Boost: Threading and mutexes in a functor - c++

I'm trying something simple with threads and mutexes in C++ with boost.
This is the code:
#include <iostream>
#include <boost/thread/thread.hpp>
class mutex_test
{
private:
boost::mutex mut;
public:
void operator()()
{
boost::mutex::scoped_lock lock(mut);
std::cout << "Hi!" << std::endl;
}
};
int main()
{
mutex_test tester;
boost::thread tester_thread(tester);
tester_thread.join();
return 0;
}
On compile, I get this error:
In file included from C:\boost/boost/thread/detail/thread.hpp:15:0,
from C:\boost/boost/thread/thread.hpp:22,
from main.cpp:3:
C:\boost/boost/thread/detail/move.hpp: In instantiation of 'typename boost::decay<T>::type boost::thread_detail::decay_copy(T&&) [with T = mutex_test&; typename boost::decay<T>::type = mutex_test]':
C:\boost/boost/thread/detail/thread.hpp:265:88: required from 'boost::thread::thread(F&&) [with F = mutex_test&]'
main.cpp:20:36: required from here
C:\boost/boost/thread/detail/move.hpp:246:37: error: use of deleted function 'mutex_test::mutex_test(const mutex_test&)'
main.cpp:5:7: note: 'mutex_test::mutex_test(const mutex_test&)' is implicitly deleted because the default definition would be ill-formed:
main.cpp:5:7: error: use of deleted function 'boost::mutex::mutex(const boost::mutex&)'
In file included from C:\boost/boost/thread/mutex.hpp:14:0,
from C:\boost/boost/thread/detail/thread.hpp:16,
from C:\boost/boost/thread/thread.hpp:22,
from main.cpp:3:
C:\boost/boost/thread/win32/mutex.hpp:29:9: error: declared here
In file included from C:\boost/boost/thread/thread.hpp:22:0,
from main.cpp:3:
C:\boost/boost/thread/detail/thread.hpp: In instantiation of 'boost::detail::thread_data<F>::thread_data(F&&) [with F = mutex_test]':
C:\boost/boost/thread/win32/thread_heap_alloc.hpp:100:72: required from 'T* boost::detail::heap_new(A1&&) [with T = boost::detail::thread_data<mutex_test>; A1 = mutex_test]'
C:\boost/boost/thread/detail/thread.hpp:214:38: required from 'static boost::detail::thread_data_ptr boost::thread::make_thread_info(F&&) [with F = mutex_test; boost::detail::thread_data_ptr = boost::intrusive_ptr<boost::detail::thread_data_base>]'
C:\boost/boost/thread/detail/thread.hpp:265:88: required from 'boost::thread::thread(F&&) [with F = mutex_test&]'
main.cpp:20:36: required from here
C:\boost/boost/thread/detail/thread.hpp:98:40: error: use of deleted function 'mutex_test::mutex_test(const mutex_test&)'
In file included from C:\boost/boost/system/system_error.hpp:14:0,
from C:\boost/boost/thread/exceptions.hpp:22,
from C:\boost/boost/thread/win32/thread_primitives.hpp:16,
from C:\boost/boost/thread/win32/thread_data.hpp:11,
from C:\boost/boost/thread/thread.hpp:15,
from main.cpp:3:
C:\boost/boost/system/error_code.hpp:214:36: warning: 'boost::system::posix_category' defined but not used [-Wunused-variable]
C:\boost/boost/system/error_code.hpp:215:36: warning: 'boost::system::errno_ecat' defined but not used [-Wunused-variable]
C:\boost/boost/system/error_code.hpp:216:36: warning: 'boost::system::native_ecat' defined but not used [-Wunused-variable]
Makefile:21: recipe for target 'main.o' failed
The error only occurs when I try to create a thread for the functor; executing it straight works fine.
Additionally, if I remove all references to mutexes and locks it works fine.
E: Had the wrong error log. Whoops.

boost::mutex is not a copyable or moveable (using boost's move implementation) type, and hence, passing it in that way to the thread will not work, since that constructor makes a copy of the functor to execute on the thread.
In your test case, you would want to use the following
boost::thread tester_thread(boost::ref(functor))
This passes it by reference, instead of by copy. Note, this also requires that the functor remain valid until the thread exits. Since you're joining the thread, that's the case here, but more complicated cases that might not be true.

Related

Compilation error 'is implicitly deleted because the default definition would be ill-formed'

I know that similar questions have been asked already, but I could not find the answer by looking at similar posts. Here is a minimal working example of my problem with the following C++ code:
#include <iostream>
#include <cstdio>
#include <fstream>
using namespace std;
class File{
public:
fstream value;
string name;
unsigned int number_of_lines;
};
void print_filename(File file){
cout << "Name of file is " << file.name << "\n";
}
int main(void){
File file;
print_filename(file);
cout << "\n";
return(0);
}
When I compile, I get the error:
example.cpp: In function ‘int main()’:
example.cpp:28:22: error: use of deleted function ‘File::File(const File&)’
print_filename(file);
^
example.cpp:7:7: note: ‘File::File(const File&)’ is implicitly deleted because the default definition would be ill-formed:
class File{
^~~~
example.cpp:7:7: error: use of deleted function ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const std::basic_fstream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]’
In file included from example.cpp:3:0:
/usr/local/include/c++/7.2.0/fstream:925:7: note: declared here
basic_fstream(const basic_fstream&) = delete;
^~~~~~~~~~~~~
example.cpp:18:6: note: initializing argument 1 of ‘void print_filename(File)’
void print_filename(File file){
^~~~~~~~~~~~~~
Do you know why?
Thank you for your help
Being able to read an error is a valuable skill! Let's do it.
error: use of deleted function ‘File::File(const File&)’
You are calling File's copy constructor, which doesn't exist.
note: ‘File::File(const File&)’ is implicitly deleted
The compiler has implicitly chosen to forbid copy construction of File.
error: use of deleted function ‘basic_fstream(const std::basic_fstream&)
It's because a copy constructor would need fstream's copy constructor, which has been deleted.
note: declared here
basic_fstream(const basic_fstream&) = delete;
^~~~~~~~~~~~~
That's the code that explicitly states that copy construction is not allowed.
note: initializing argument 1 of ‘void print_filename(File)’
void print_filename(File file){
Here is where the problem exists in your code.
The solution, as commented, is to not make a copy. It's not needed.
Pass by reference instead.

Pass a refrence for thread constructor to bind it to function fails?

I have a void fun(vector<int> & v) and I want to pass a vector to it when instantiating a thread thread t(fun, v);. In C++14 clang 4 compilation fails, in MSVC it runs passing a copy to function.
#include <thread>
#include <vector>
#include <iostream>
using namespace std;
void fun(vector<int> & v) {
v.push_back(13);
}
int main(){
vector<int> v;
thread t(fun, v);
t.join();
cout << v.size();
}
example of gcc 5.4.0 error:
In file included from /usr/include/c++/5/thread:39:0,
from source_file.cpp:1: /usr/include/c++/5/functional: In instantiation of ‘struct
std::_Bind_simple))(std::vector&)>’:
/usr/include/c++/5/thread:137:59: required from
‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void
(&)(std::vector&); _Args = {std::vector
&}]’ source_file.cpp:12:21: required from here /usr/include/c++/5/functional:1505:61: error: no type named ‘type’ in
‘class std::result_of))(std::vector&)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^ /usr/include/c++/5/functional:1526:9: error: no type named ‘type’ in
‘class std::result_of))(std::vector&)>’
_M_invoke(_Index_tuple<_Indices...>)
So 1) what is c++ standard stand on this issue; 2) is there a way around it (not passing a pointer and not +1 extra lambda expression as wrapper)?
As pointed out by Galik in the comment, all you need is std::ref():
thread t(fun, std::ref(v));
Why ?
This is because your function fun() expects a reference to an lvalue. However when you construct your thread(), a copy of your arguments will be passed in the new thread. Unfortunately, the compiler will not be able to instantiate the templates behind the scene with a reference to a temporary copy in this case.
Putting the std::ref(), will cause the reference to the original to be used, and make the whole thing to work as expected.

C++ Passing a reference variable to the thread in g++-4.7.4

I need to start a thread passing complex parameters (std::thread<>) as a parameter when the thread starts. I´m using `std::ref. This code works fine with updated environments (g++-4.8.2 running on Ubuntu).
Now I have to compile this same code in a old compiler (g++4.7.4) and I´m getting errors.
The code is shown below, as well as the error:
ReaderThread.hpp
class ReaderThread {
void start(Reader reader, SyncController &syncController);
}
ReaderThread.cpp
void ReaderThread::start(Reader reader, SyncController &syncController)
{
Do something...
}
main.cpp
int main()
{
...do stuff...
/*
* Create and start the reader thread. The created object must live
* during the whole thread life.
* std::ref is used to pass as reference
*/
myReader = ReaderFactory(params);
std::shared_ptr<ReaderThread> ptr(new ReaderThread);
std::thread th(&ReaderThread::start, ptr, myReader, std::ref(syncController));
...do other stuff...
}
ERROR:
In file included from /usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/bits/move.h:57:0,
from /usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/bits/stl_pair.h:61,
from /usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/bits/stl_algobase.h:65,
from /usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/bits/char_traits.h:41,
from /usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/ios:41,
from /usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/ostream:40,
from /usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/iostream:40,
from ./main.cpp:11:
/usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/type_traits: In instantiation of 'struct std::_Result_of_impl<false, false, std::_Mem_fn<void (ReaderThread::*)(Reader, SyncController&)>, std::shared_ptr<ReaderThread>, Reader, std::reference_wrapper<SyncController> >':
/usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/type_traits:1857:12: required from 'class std::result_of<std::_Mem_fn<void (ReaderThread::*)(Reader, SyncController&)>(std::shared_ptr<ReaderThread>, Reader, std::reference_wrapper<SyncController>)>'
/usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/functional:1563:61: required from 'struct std::_Bind_simple<std::_Mem_fn<void (ReaderThread::*)(Reader, SyncController&)>(std::shared_ptr<aeirtuthread::ReaderThread>, Reader, std::reference_wrapper<SyncController>)>'
/usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/thread:133:9: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (ReaderThread::*)(Reader, SyncController&); _Args = {std::shared_ptr<ReaderThread>&, Reader&, std::reference_wrapper<SyncController>}]'
./aeirtu/aeirtu/main.cpp:155:96: required from here
/usr/gcc-4.7.4/lib/gcc/i586-pc-linux-gnu/4.7.4/../../../../include/c++/4.7.4/type_traits:1834:9: error: no match for call to '(std::_Mem_fn<void (ReaderThread::*)(Reader, SyncController&)>) (std::shared_ptr<ReaderThread>, Reader, std::reference_wrapper<SyncController>)'
I can´t find out if this error is being caused by the use of std::ref on older compilers or from something different.
Help appreciated fo find a fix that would be supported by 4.7.4 and compile my code.
gcc 4.7 doesn't seem to be able to handle shared_ptr (or unique_ptr for this matter) provided as an object. It works fine with natural pointer, though - so one possible solution would be to replace thread creation with following (if appropriate, of course):
std::thread th(&ReaderThread::start, &myThread, myReader, std::ref(syncController));
Now, if this is not feasible and true allocated pointers are needed, following is a replacement for your idea:
std::thread th(
[ptr, &syncController, myReader] () {
ptr->start(myReader, syncController);
}
);
}
In this example, synController is passed by reference, everything else by value, same way as in your post.

Error: no known conversion for

So this is what I currently have, with the Scanner provided by my professor.
#include "Similarity.h"
#include "Scanner.h"
using namespace std;
int Similarity::readData(Scanner inFile){
int similarityInputSize;
vector< vector<int> > containingVector;
bool nextValueFound;
similarityInputSize = inFile.nextInt();
int lineCount = 0;
while(inFile.hasNext()){
containingVector.push_back(vector<int>());
for(int i = 0; i < similarityInputSize; i++){
containingVector[lineCount].push_back(inFile.nextInt());
}
lineCount++;
}
for(int i = 0; i < containingVector.size(); i++){
for(int j = 0; j < similarityInputSize; i++){
cout << containingVector[i][j] << " ";
}
cout << endl;
}
return 0;
}
The Main class is given to us and involves a call by value not by reference, which my professor got to work.
the errors I receive are:
In file included from /usr/include/c++/4.7/ios:43:0,
from /usr/include/c++/4.7/ostream:40,
from /usr/include/c++/4.7/iostream:40,
from ../../Utilities/Utils.h:17,
from Main.h:11:
/usr/include/c++/4.7/bits/ios_base.h: In copy constructor ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’:
/usr/include/c++/4.7/bits/ios_base.h:788:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
In file included from /usr/include/c++/4.7/ios:45:0,
from /usr/include/c++/4.7/ostream:40,
from /usr/include/c++/4.7/iostream:40,
from ../../Utilities/Utils.h:17,
from Main.h:11:
/usr/include/c++/4.7/bits/basic_ios.h:64:11: error: within this context
In file included from ../../Utilities/Utils.h:18:0,
from Main.h:11:
/usr/include/c++/4.7/fstream: In copy constructor ‘std::basic_ifstream<char>::basic_ifstream(const std::basic_ifstream<char>&)’:
/usr/include/c++/4.7/fstream:420:11: note: synthesized method ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’ first required here
In file included from /usr/include/c++/4.7/ios:44:0,
from /usr/include/c++/4.7/ostream:40,
from /usr/include/c++/4.7/iostream:40,
from ../../Utilities/Utils.h:17,
from Main.h:11:
/usr/include/c++/4.7/streambuf: In copy constructor ‘std::basic_filebuf<char>::basic_filebuf(const std::basic_filebuf<char>&)’:
/usr/include/c++/4.7/streambuf:800:7: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const __streambuf_type&) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_streambuf<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>]’ is private
In file included from ../../Utilities/Utils.h:18:0,
from Main.h:11:
/usr/include/c++/4.7/fstream:69:11: error: within this context
/usr/include/c++/4.7/fstream: In copy constructor ‘std::basic_ifstream<char>::basic_ifstream(const std::basic_ifstream<char>&)’:
/usr/include/c++/4.7/fstream:420:11: note: synthesized method ‘std::basic_filebuf<char>::basic_filebuf(const std::basic_filebuf<char>&)’ first required here
In file included from Main.h:12:0:
../../Utilities/Scanner.h: In copy constructor ‘Scanner::Scanner(const Scanner&)’:
../../Utilities/Scanner.h:27:7: note: synthesized method ‘std::basic_ifstream<char>::basic_ifstream(const std::basic_ifstream<char>&)’ first required here
Main.cpp: In function ‘int main(int, char**)’:
Main.cpp:58:31: note: synthesized method ‘Scanner::Scanner(const Scanner&)’ first required here
In file included from Main.h:14:0:
Similarity.h:23:9: error: initializing argument 1 of ‘int Similarity::readData(Scanner)’
So I don't quite understand what happened. Everywhere I looked said that the issue would be fixed by a call by reference not by value. However, his provided code does not include any call by references, which makes me assume its a more subtle error (or its so big that it's blinding me). Nevertheless, I changed it anyways and it gave me these errors:
Similarity.cpp:12:5: error: prototype for ‘int Similarity::readData(Scanner&)’ does not match any in class ‘Similarity’
Similarity.h:23:9: error: candidate is: int Similarity::readData(Scanner)
Main.cpp: In function ‘int main(int, char**)’:
Main.cpp:58:32: error: no matching function for call to ‘Similarity::readData(Scanner*)’
Main.cpp:58:32: note: candidate is:
In file included from Main.h:14:0:
Similarity.h:23:9: note: int Similarity::readData(Scanner)
Similarity.h:23:9: note: no known conversion for argument 1 from ‘Scanner*’ to ‘Scanner’
Anything you can tell me at all will be a help.
Thanks in advance!
I'm guessing Scanner isn't meant to be copied. The syntax:
int Similarity::readData(Scanner inFile){
implies that Scanner will be copied from the passed in variable to the variable received by this method via Scanner's copy constructor.
Scanner sounds like something that deals with iostreams under the hood. Streams in the iostreams library do not have copy constructors.
I'm not entirely clear how you tried to pass by reference, but you need to change the signature in this file and the corresponding .h file to:
int Similarity::readData(Scanner& inFile){
And you should have no problem. readData now receives a reference to the passed in file. This is essentially an alias of the thing passed in -- anything you do to it will be reflected on the object that was passed in.

/boost/lockfree/queue.hpp: error: static assertion failed: (boost::has_trivial_destructor<T>::value)

I'm trying to substitute boost::lockfree::queue for std::queue in this file https://github.com/zaphoyd/websocketpp/blob/experimental/examples/broadcast_server/broadcast_server.cpp
I've added #include <boost/lockfree/queue.hpp>; changed line 130, std::queue<action> m_actions;, to boost::lockfree::queue<action> m_actions;; removed all lines having to do with locking; and changed line 103, m_actions.pop();, to m_actions.pop(a);.
I get these errors when I scons broadcast_server_lockfree in the project root after adding broadcast_server_lockfree = SConscript('#/broadcast_server_lockfree/SConscript',variant_dir = builddir + 'broadcast_server_lockfree',duplicate = 0) to the project root's SConstruct and using broadcast_server's SConstruct in the broadcast_server_lockfree directory:
root#server:~/websocketpp-experimental# scons broadcast_server_lockfree
scons: Reading SConscript files ...
C++11 build environment partially enabled
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build/release/broadcast_server_lockfree
g++ -o build/release/broadcast_server_lockfree/broadcast_server_lockfree.o -c -std=c++0x -Wall -Wcast-align -isystem /root/boost_1_53_0 -DNDEBUG -D_WEBSOCKETPP_CPP11_MEMORY_ -D_WEBSOCKETPP_CPP11_FUNCTIONAL_ -D_WEBSOCKETPP_CPP11_SYSTEM_ERROR_ -D_WEBSOCKETPP_CPP11_RANDOM_DEVICE_ -D_WEBSOCKETPP_NOEXCEPT_ -I. broadcast_server_lockfree/broadcast_server_lockfree.cpp
In file included from broadcast_server_lockfree/broadcast_server_lockfree.cpp:10:0:
/root/boost_1_53_0/boost/lockfree/queue.hpp: In instantiation of 'class boost::lockfree::queue<action>':
broadcast_server_lockfree/broadcast_server_lockfree.cpp:139:36: required from here
/root/boost_1_53_0/boost/lockfree/queue.hpp:79:5: error: static assertion failed: (boost::has_trivial_destructor<T>::value)
/root/boost_1_53_0/boost/lockfree/queue.hpp:83:5: error: static assertion failed: (boost::has_trivial_assign<T>::value)
broadcast_server_lockfree/broadcast_server_lockfree.cpp: In member function 'void broadcast_server::process_messages()':
broadcast_server_lockfree/broadcast_server_lockfree.cpp:111:34: error: 'class boost::lockfree::queue<action>' has no member named 'front'
broadcast_server_lockfree/broadcast_server_lockfree.cpp:117:55: error: 'm_connection_lock' was not declared in this scope
broadcast_server_lockfree/broadcast_server_lockfree.cpp:120:55: error: 'm_connection_lock' was not declared in this scope
broadcast_server_lockfree/broadcast_server_lockfree.cpp:123:55: error: 'm_connection_lock' was not declared in this scope
In file included from broadcast_server_lockfree/broadcast_server_lockfree.cpp:10:0:
/root/boost_1_53_0/boost/lockfree/queue.hpp: In instantiation of 'boost::lockfree::queue<T, A0, A1, A2>::~queue() [with T = action; A0 = boost::parameter::void_; A1 = boost::parameter::void_; A2 = boost::parameter::void_]':
broadcast_server_lockfree/broadcast_server_lockfree.cpp:41:24: required from here
/root/boost_1_53_0/boost/lockfree/queue.hpp:229:11: error: no matching function for call to 'action::action()'
/root/boost_1_53_0/boost/lockfree/queue.hpp:229:11: note: candidates are:
broadcast_server_lockfree/broadcast_server_lockfree.cpp:32:5: note: action::action(action_type, websocketpp::endpoint<websocketpp::connection<websocketpp::config::asio>, websocketpp::config::asio>::message_ptr)
broadcast_server_lockfree/broadcast_server_lockfree.cpp:32:5: note: candidate expects 2 arguments, 0 provided
broadcast_server_lockfree/broadcast_server_lockfree.cpp:31:5: note: action::action(action_type, websocketpp::connection_hdl)
broadcast_server_lockfree/broadcast_server_lockfree.cpp:31:5: note: candidate expects 2 arguments, 0 provided
broadcast_server_lockfree/broadcast_server_lockfree.cpp:30:8: note: action::action(const action&)
broadcast_server_lockfree/broadcast_server_lockfree.cpp:30:8: note: candidate expects 1 argument, 0 provided
In file included from broadcast_server_lockfree/broadcast_server_lockfree.cpp:10:0:
/root/boost_1_53_0/boost/lockfree/queue.hpp: In instantiation of 'boost::lockfree::queue<T, A0, A1, A2>::node::node(boost::lockfree::queue<T, A0, A1, A2>::node::handle_type) [with T = action; A0 = boost::parameter::void_; A1 = boost::parameter::void_; A2 = boost::parameter::void_; boost::lockfree::queue<T, A0, A1, A2>::node::handle_type = boost::lockfree::queue<action>::node*]':
/root/boost_1_53_0/boost/lockfree/detail/freelist.hpp:82:13: required from 'T* boost::lockfree::detail::freelist_stack<T, Alloc>::construct(const ArgumentType&) [with bool ThreadSafe = true; bool Bounded = false; ArgumentType = boost::lockfree::queue<action>::node*; T = boost::lockfree::queue<action>::node; Alloc = std::allocator<boost::lockfree::queue<action>::node>]'
/root/boost_1_53_0/boost/lockfree/queue.hpp:126:75: required from 'void boost::lockfree::queue<T, A0, A1, A2>::initialize() [with T = action; A0 = boost::parameter::void_; A1 = boost::parameter::void_; A2 = boost::parameter::void_]'
/root/boost_1_53_0/boost/lockfree/queue.hpp:166:9: required from 'boost::lockfree::queue<T, A0, A1, A2>::queue() [with T = action; A0 = boost::parameter::void_; A1 = boost::parameter::void_; A2 = boost::parameter::void_]'
broadcast_server_lockfree/broadcast_server_lockfree.cpp:41:24: required from here
/root/boost_1_53_0/boost/lockfree/queue.hpp:109:52: error: no matching function for call to 'action::action()'
/root/boost_1_53_0/boost/lockfree/queue.hpp:109:52: note: candidates are:
broadcast_server_lockfree/broadcast_server_lockfree.cpp:32:5: note: action::action(action_type, websocketpp::endpoint<websocketpp::connection<websocketpp::config::asio>, websocketpp::config::asio>::message_ptr)
broadcast_server_lockfree/broadcast_server_lockfree.cpp:32:5: note: candidate expects 2 arguments, 0 provided
broadcast_server_lockfree/broadcast_server_lockfree.cpp:31:5: note: action::action(action_type, websocketpp::connection_hdl)
broadcast_server_lockfree/broadcast_server_lockfree.cpp:31:5: note: candidate expects 2 arguments, 0 provided
broadcast_server_lockfree/broadcast_server_lockfree.cpp:30:8: note: action::action(const action&)
broadcast_server_lockfree/broadcast_server_lockfree.cpp:30:8: note: candidate expects 1 argument, 0 provided
scons: *** [build/release/broadcast_server_lockfree/broadcast_server_lockfree.o] Error 1
scons: building terminated because of errors.
I know next to nothing about c++, and searches on the error have yielded nothing (since I have no idea what I'm reading).
Here's the boost::lockfree::queue example if it helps. http://boost-sandbox.sourceforge.net/doc/html/lockfree/examples.html
Please show me how to correct this.
action
struct action {
action(action_type t, connection_hdl h) : type(t), hdl(h) {}
action(action_type t, server::message_ptr m) : type(t), msg(m) {}
action_type type;
websocketpp::connection_hdl hdl;
server::message_ptr msg;
};
From the docs:
T must have a copy constructor, a trivial assignment operator, and a trivial destructor.
Thus your action class must look like the following:
class action
{
public:
action(const action& rhs) { ... }
//Implicitly defined destructor for itself and all member variables
//Implicitly defined operator= for itself and all member variables
};
The static_asserts are complaining because your destructor and operator= are not implicitly defined by the compiler (or this is the case for at least one member variable of action).
Edit: I've had a quick look at the repo - I can't seem to find connection_hdl, and there is no message_ptr in template <typename endpoint> class server. Either way, one of websocketpp::connection_hdl hdl or server::message_ptr msg does not satisfy the above conditions. Just "dropping in" a lockfree queue instead of using a std::queue is likely a non-trivial task which will require a number of changes.
This question has been answer well by the above posting. Here I will provide more examples. The fruitful discussion gave a lots of guidance please read them. The real matter is the requirement for the template type of the queue. For practicality, let's look at some real use cases.
namespace lkf=boost::lockfree;
vector<lkf::spsc_queue<pair<Fastq*,int>, lkf::capacity<100>>> datastore;
//lkf::queue<pair<char*,char*>, lkf::capacity<100>> pile1, pile2; //failed assert
lkf::queue<pair<char*,char*>*, lkf::capacity<100>> pile1, pile2;
The first line in the code passed the compiler (because it is spac_queue), but the second line pair failed the compiler (due to boost::ASSERT):
/usr/local/include/boost/lockfree/queue.hpp:99:5: error: static assertion failed: (boost::has_trivial_assign<T>::value)
BOOST_STATIC_ASSERT((boost::has_trivial_assign<T>::value));
After converting pair to pointer type (line 3), the compiler is happy.
Could be boost assertion needs to be updated? Converting to pointer is one quick trick, may not be the best.
The boost lockfree::queue has three Requirements:
T must have a copy constructor
T must have a trivial assignment operator
T must have a trivial destructor
spsc_queue has two:
T must have a default constructor
T must be copyable
I got this error when I used std::string for the queue item type.
boost::lockfree::queue<string>(10000)
As many good people have pointed out in the answers here and here, string is not allowed to be used for boost::lockfree::queue.
It does compiled with char *
boost::lockfree::queue<char*>(10000)