
Greetings. I have a class that wraps a boost::thread object, and I would like to specify certain thread attributes at construction time. My first attempt looked basically like this: struct my_thread { static boost::thread::attributes getThreadAttr() { boost::thread::attributes attrs; attrs.set_stack_size( 256 * 1024 ); return attrs; } my_thread( Runnable func ) : thread_( getThreadAttr(), func ) {} boost::thread thread_; }; But that fails: g++ -std=c++0x -o thread-attr thread-attr.cpp \ -lboost_thread-mt -lboost_system -pthread ... /usr/include/boost/thread/detail/thread.hpp:191:9: note: \ template argument deduction/substitution failed: thread-attr.cpp:48:42: note: cannot convert ‘my_thread::getThreadAttr()()’ (type \ ‘boost::thread::attributes {aka boost::thread_attributes}’) to type ‘boost::thread::attributes& {aka boost::thread_attributes&}’ Replacing 'getThreadAttr' with a method that returns a non-const reference to internal static variables allows the program to compile and run successfully: static boost::thread::attributes & getThreadAttr() { static boost::thread::attributes attrs; static bool init = false; if ( ! init ) { attrs.set_stack_size( 256 * 1024 ); init = true; } return attrs; } The full program, with Linux compile lines, can be found at the bottom of this message and also at: http://foiani.home.dyndns.org/~tony/boost/thread-attr.cpp I did find a closely-related question on StackOverflow: http://stackoverflow.com/questions/13868619 Where Vicente replied (http://stackoverflow.com/a/13894968/784478): The needed overload template <class F, class Arg, class ...Args> thread(attributes const& attrs, F&& f, Arg&& arg, Args&&... args) is defined only if the compiler supports variadic templates and rvalue references. This could explain your problem. I guess the documentation could be improved to signal this clearly. Please could you create a Trac ticket to follow this issue? However, the compiler I'm using (g++ 4.7.2) has supported both of these features for years. According to this page: http://gcc.gnu.org/projects/cxx0x.html g++ has supported both of these features since 4.3. Josef_K (on freenode IRC #boost channel) was kind enough to try the sample code in their own environment, and they encountered the same errors on both g++ 4.8.1 and clang 3.4. The most likely explanation is that I'm doing something stupid. If anyone has the time to hit me with the clue-by-four, I would appreciate it. There is the possibility that Boost.Thread v4 fixes this (I'm on 1_51_0, which is Boost.Thread v3.0.1). I'd rather not try to transition libraries at this point, but if it has been fixed, confirmation would be welcome. For now, I'll most likely implement the "return reference to internal static" method in my project. It's a bit racy, but since I do all my thread creation through this one routine, I should be able to manage it. Anyway. I'm left feeling that there is a gap somewhere; whether it's in my understanding, in the older version of Boost.Threads, in compiler support / quirks, or elsewhere, I don't know. Regardless, thanks for the excellent library, and happy hacking! Best regards, Anthony Foiani Sample program follows: ======================================================================== // this should work: // g++ -std=c++0x -o thread-attr thread-attr.cpp -lboost_thread-mt -lboost_system -pthread // // this explodes: // g++ -std=c++0x -o thread-attr thread-attr.cpp -DRVALUE_REFERENCE_DOOM -lboost_thread-mt -lboost_system -pthread #include <iostream> #include <boost/function.hpp> #include <boost/thread.hpp> typedef boost::function< void ( void ) > Runnable; struct my_thread { #ifdef RVALUE_REFERENCE_DOOM // this doesn't work. static boost::thread::attributes getThreadAttr() { boost::thread::attributes attrs; attrs.set_stack_size( 256 * 1024 ); return attrs; } #else // this does work, but needs more structure before it can be // considered safe. static boost::thread::attributes & getThreadAttr() { static boost::thread::attributes attrs; static bool init = false; if ( ! init ) { attrs.set_stack_size( 256 * 1024 ); init = true; } return attrs; } #endif my_thread( Runnable func ) : thread_( getThreadAttr(), func ) {} void join() { thread_.join(); } boost::thread thread_; }; void foo() { std::cout << "foo!" << std::endl; } int main( int argc, char * argv [] ) { my_thread t( foo ); t.join(); return 0; }