Boost C++ Libraries: Ticket #9303: packaged_task<R(Argtypes)> does not compile using c++03 and Cmake 2.8.9 https://svn.boost.org/trac10/ticket/9303 <p> Setup consists of client(s), a server, and device(s). </p> <p> A client interacts with a device by sending requests to the server. These requests are examined and routed to the appropriate device. Requests are handled asynchronously, and are occasionally queued up via boost::asio::io_service::strand for various reasons. </p> <p> It appears as if packaged_task has a few different templates to choose from: </p> <p> packaged_task&lt;R&gt; packaged_task&lt;R()&gt; packaged_task&lt;R(<a class="missing wiki">ArgTypes</a>)&gt; </p> <p> To ensure that I was using the function correctly, I started simple; using the simple example on the boost::futures page as a starting point. From there, I created four simple functions: </p> <p> int return, no parameters. int return, with parameters. std::string return, no parameters. std::string return, with parameters. Test functions </p> <pre class="wiki">std::string ans("forty two"); int int_no_params() { return 42; } int int_with_params(int param) { return param; } std::string string_no_params() { return std::string("forty two"); } std::string string_with_params(std::string &amp; param) // Have tried both with and without '&amp;' { return param; } </pre><p> EXAMPLE 1: </p> <pre class="wiki">int function(void) //! Compiles and produces correct result. { boost::packaged_task&lt;int()&gt; example(int_no_params); boost::future&lt;int&gt; f = example.get_future(); boost::thread task(boost::move(example)); int answer = f.get(); std::cout &lt;&lt; "Answer to life and whatnot, in English: " &lt;&lt; answer &lt;&lt; std::endl; task.join(); } </pre><p> EXAMPLE 2: </p> <pre class="wiki"> std::string function(void) //! Compiles and produces correct result. { boost::packaged_task&lt;std::string()&gt; example(string_no_params); boost::future&lt;std::string&gt; f = example.get_future(); boost::thread task(boost::move(example)); std::string answer = f.get(); std::cout &lt;&lt; "string_no_params: " &lt;&lt; answer &lt;&lt; std::endl; task.join(); } </pre><p> EXAMPLE 3: </p> <pre class="wiki"> std::string(std::string&amp; param) No threading //! Doesn't compile. //! error: variable ‘boost::packaged_task&lt;std::basic_string&lt;char&gt;(std::basic_string&lt;char&gt;&amp;)&gt; example’ has initializer but incomplete type { boost::packaged_task&lt;std::string(std::string&amp;)&gt; example(string_with_params); boost::future&lt;std::string&gt; f = example.get_future(); example(ans); std::string answer = f.get(); std::cout &lt;&lt; "string_with_params: " &lt;&lt; answer &lt;&lt; std::endl; } </pre><p> EXAMPLE 4: </p> <pre class="wiki"> using boost::threading //! Doesn't compile. //! error: variable ‘boost::packaged_task&lt;std::basic_string&lt;char&gt;(std::basic_string&lt;char&gt;&amp;)&gt; example’ has initializer but incomplete type { boost::packaged_task&lt;std::string(std::string&amp;)&gt; example(string_with_params); boost::future&lt;std::string&gt; f = example.get_future(); boost::thread task(boost::move(example), ans); std::string answer = f.get(); std::cout &lt;&lt; "string_with_params: " &lt;&lt; answer &lt;&lt; std::endl; task.join(); } </pre><p> EXAMPLE 5: </p> <pre class="wiki">//Using extended initializers in packaged_task declaration //! Doesn't compile in C++03, C++11 only. //! error: extended initializer lists only available with -std=c++11 or -std=gnu++11 [-Werror] { boost::packaged_task&lt;std::string(std::string&amp;)&gt; example { boost::bind(&amp;string_with_params, ans) }; boost::future&lt;std::string&gt; f = example.get_future(); boost::thread task(boost::move(example), ans); std::string answer = f.get(); std::cout &lt;&lt; "string_with_params: " &lt;&lt; answer &lt;&lt; std::endl; task.join(); } </pre><p> EXAMPLE 6: </p> <pre class="wiki">//Threaded, using shared_ptr //The following use typedef boost::packaged_task&lt;std::string(std::string&amp;)&gt; task_t; //Because packaged tasks can't be copied, binding //shared_ptr&lt;T&gt;::operator() to task was a suggested solution found on stackoverflow. // error: invalid use of incomplete type ‘class boost::packaged_task&lt;std::basic_string&lt;char&gt;(std::basic_string&lt;char&gt;&amp;)&gt;’ // error: incomplete type ‘task_t {aka boost::packaged_task&lt;std::basic_string&lt;char&gt;(std::basic_string&lt;char&gt;&amp;)&gt;}’ used in nested name specifier // boost/thread/future.hpp:1320:11: error: declaration of ‘class boost::packaged_task&lt;std::basic_string&lt;char&gt;(std::basic_string&lt;char&gt;&amp;)&gt;’ { boost::shared_ptr&lt;task_t&gt; example = boost::make_shared&lt;task_t&gt;(boost::bind(&amp;string_with_params, ans)); boost::future&lt;std::string&gt; f = example-&gt;get_future(); boost::thread task(boost::bind(&amp;task_t::operator(), example)); std::string answer = f.get(); std::cout &lt;&lt; "string_with_params: " &lt;&lt; answer &lt;&lt; std::endl; task.join(); } </pre><p> EXAMPLE 7: </p> <pre class="wiki">//Using boost::asio::io_service and boost::bind // error: invalid use of incomplete type ‘class boost::packaged_task(std::basic_string&amp;)&gt;’ // error: incomplete type ‘task_t {aka boost::packaged_task(std::basic_string&amp;)&gt;}’ used in nested name specifier // boost/thread/future.hpp:1320:11: error: declaration of ‘class boost::packaged_task(std::basic_string&amp;)&gt;’ { boost::asio::io_service io_service; boost::thread_group threads; boost::asio::io_service::work work(io_service); for (int i = 0; i &lt; 3; ++i) { threads.create_thread(boost::bind(&amp;boost::asio::io_service::run, &amp;io_service)); } boost::shared_ptr&lt;task_t&gt; example = boost::make_shared&lt;task_t&gt;(boost::bind(&amp;string_with_params, ans)); boost::future&lt;std::string&gt; f = example-&gt;get_future(); io_service.post(boost::bind(&amp;task_t::operator(), example)); std::string answer = f.get(); std::cout &lt;&lt; "string_with_params: " &lt;&lt; answer &lt;&lt; std::endl; threads.join_all(); } </pre><p> It seems like future.hpp has a problem that is preventing the proper template from being used. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9303 Trac 1.4.3 anonymous Fri, 25 Oct 2013 18:22:55 GMT attachment set https://svn.boost.org/trac10/ticket/9303 https://svn.boost.org/trac10/ticket/9303 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">packagedTestTest.cpp</span> </li> </ul> Ticket viboes Sat, 26 Oct 2013 11:13:22 GMT owner, status changed https://svn.boost.org/trac10/ticket/9303#comment:1 https://svn.boost.org/trac10/ticket/9303#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Anthony Williams</span> to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> This is normal if you are using BOOST_THREAD_VERSION = 2, which is the default. </p> <p> If you can not use BOOST_THREAD_VERSION = 2, use packaged_task&lt;R&gt; instead of packaged_task&lt;R()&gt;, but you couldn't work with non-nullary functions (you must then use boost::bind). </p> <p> Which version are you using? Which compiler? </p> Ticket anonymous Tue, 29 Oct 2013 19:53:04 GMT <link>https://svn.boost.org/trac10/ticket/9303#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9303#comment:2</guid> <description> <p> I'm sorry, I thought I included the compiler information in the ticket. </p> <p> Our build(s) use CMake 2.8.8, and gcc 4.6 (with some variance depending on system). </p> <p> We are using BOOST_THREAD_VERSION = 4. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 02 Nov 2013 13:40:22 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9303#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9303#comment:3</guid> <description> <p> I'm really sorry. This doesn't works yet for non C++98 compilers. Here it is the code </p> <pre class="wiki">#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template&lt;typename R, typename ...ArgTypes&gt; class packaged_task&lt;R(ArgTypes...)&gt; { typedef boost::shared_ptr&lt;detail::task_base_shared_state&lt;R(ArgTypes...)&gt; &gt; task_ptr; boost::shared_ptr&lt;detail::task_base_shared_state&lt;R(ArgTypes...)&gt; &gt; task; #else template&lt;typename R&gt; class packaged_task&lt;R()&gt; { typedef boost::shared_ptr&lt;detail::task_base_shared_state&lt;R()&gt; &gt; task_ptr; boost::shared_ptr&lt;detail::task_base_shared_state&lt;R()&gt; &gt; task; #endif </pre><p> As you can see, only if BOOST_THREAD_PROVIDES_VARIADIC_THREAD you can use </p> <pre class="wiki">boost::packaged_task&lt;std::string(std::string&amp;)&gt; </pre><p> I'm not sure Example 5 is a bug on Boost.Thread, I suspect that this is just not supported in C++03. </p> <p> Unfortunately I have no time to develop this for C++03 compilers. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 02 Nov 2013 14:16:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9303#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9303#comment:4</guid> <description> <p> Anyway, I have tried to compile your example with C++11 and there are some issues. I will take a deeper look. </p> <p> The line in example 6 seems suspect </p> <pre class="wiki"> boost::thread task(boost::bind(&amp;task_t::operator(), example)); </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 02 Nov 2013 14:35:52 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9303#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9303#comment:5</guid> <description> <p> This doesn't solves the issues,but I missed this code </p> <pre class="wiki">svn diff future.hpp Index: future.hpp =================================================================== --- future.hpp (revision 86540) +++ future.hpp (working copy) @@ -2766,12 +2766,18 @@ private: task_shared_state(task_shared_state&amp;); public: +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK &amp;&amp; defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + R (*f)(BOOST_THREAD_RV_REF(ArgTypes) ... ); + task_shared_state(R (*f_)(BOOST_THREAD_RV_REF(ArgTypes) ... )): + f(f_) + {} +#else R (*f)(); task_shared_state(R (*f_)()): f(f_) {} +#endif - #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK &amp;&amp; defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) { @@ -2848,12 +2854,18 @@ private: task_shared_state(task_shared_state&amp;); public: +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK &amp;&amp; defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + R&amp; (*f)(BOOST_THREAD_RV_REF(ArgTypes) ... ); + task_shared_state(R&amp; (*f_)(BOOST_THREAD_RV_REF(ArgTypes) ... )): + f(f_) + {} +#else R&amp; (*f)(); task_shared_state(R&amp; (*f_)()): f(f_) {} +#endif - #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK &amp;&amp; defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) { </pre><p> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Thu, 27 Feb 2014 22:22:11 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9303#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9303#comment:6</guid> <description> <p> Hi and sorry for the delay. </p> <p> You need to use boost::ref() while passing by reference </p> <pre class="wiki"> boost::thread task(boost::move(example), boost::ref(ans)); </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 01 Mar 2014 07:42:30 GMT</pubDate> <title>status changed; resolution set; milestone deleted https://svn.boost.org/trac10/ticket/9303#comment:7 https://svn.boost.org/trac10/ticket/9303#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">worksforme</span> </li> <li><strong>milestone</strong> <span class="trac-field-deleted">To Be Determined</span> </li> </ul> <p> Committed the examples with the fixes </p> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/7d4f485ade79c0fbb6434402e52045040ef000c9"><span class="icon">​</span>https://github.com/boostorg/thread/commit/7d4f485ade79c0fbb6434402e52045040ef000c9</a> </p> Ticket