2 problem:
#include <iostream>
#include <string>
#include <regex>
int main() {
std::u32string lines[] = {U"Roses are #ff0000",
U"violets are #0000ff",
U"all of my base are belong to you"};
std::basic_regex<char32_t> color_regex(U"#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})");
/*
for (const auto &line : lines) {
std::cout << line << ": "
<< std::regex_search(line, color_regex) << '\n';
}
std::smatch color_match;
for (const auto &line : lines) {
std::regex_search(line, color_match, color_regex);
std::cout << "matches for '" << line << "'\n";
for (size_t i = 0; i < color_match.size(); ++i) {
std::ssub_match sub_match = color_match[i];
std::string sub_match_str = sub_match.str();
std::cout << i << ": " << sub_match_str << '\n';
}
}
*/
return 0;
}
compile with gcc : it work:
g++ -g -O0 -std=c++11 regexp.cpp -o executable
compile with clang: it not work at all:
clang++ -g -O0 -std=c++11 regexp.cpp -o executable
execute with gcc generated file:
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Abandon (core dumped)
error in clang compilation:
In file included from regexp.cpp:3:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/regex:60:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:413:20: error: non-type template argument is not a constant expression
std::bitset<1 << (8 * sizeof(_CharT))>,
^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:398:53: note: in instantiation of template class 'std::__detail::_BracketMatcher<std::regex_traits<char32_t>, false, false>' requested here
_BracketMatcher<_TraitsT, __icase, __collate> __matcher
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:316:25: note: in instantiation of function template specialization 'std::__detail::_Compiler<std::regex_traits<char32_t>
>::_M_insert_character_class_matcher<false, false>' requested here
__INSERT_REGEX_MATCHER(_M_insert_character_class_matcher);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:288:8: note: expanded from macro '__INSERT_REGEX_MATCHER'
__func<false, false>(args);\
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:136:17: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_atom' requested here
if (this->_M_atom())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:118:17: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_term' requested here
if (this->_M_term())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:97:13: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_alternative' requested here
this->_M_alternative();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:82:13: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_disjunction' requested here
this->_M_disjunction();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:155:14: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_Compiler' requested here
return _Cmplr(__first, __last, __traits, __flags)._M_get_nfa();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex.h:524:27: note: in instantiation of function template specialization 'std::__detail::__compile_nfa<std::regex_traits<char32_t> >' requested here
_M_automaton(__detail::__compile_nfa(_M_original_str.c_str(),
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex.h:452:9: note: in instantiation of function template specialization 'std::basic_regex<char32_t, std::regex_traits<char32_t> >::basic_regex<const
char32_t *>' requested here
: basic_regex(__p, __p + _Rx_traits::length(__p), __f)
^
regexp.cpp:10:29: note: in instantiation of member function 'std::basic_regex<char32_t, std::regex_traits<char32_t> >::basic_regex' requested here
std::basic_regex<char32_t> color_regex(U"#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})");
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:413:22: note: shift count 32 >= width of type 'int' (32 bits)
std::bitset<1 << (8 * sizeof(_CharT))>,
^
...
...
...
...
Have someone already try it?
$ clang --version
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix
$ g++ --version
g++ (Ubuntu 4.9.1-3ubuntu2~14.04.1) 4.9.1
According to this reference
Two specializations of std::regex_traits are defined by the standard library:
std::regex_traits<char>
std::regex_traits<wchar_t>
These specializations make it possible to use std::basic_regex<char> (aka std::regex) and std::basic_regex<wchar_t> (aka std::wregex), but in order to use, for example, std::basic_regex<char32_t>, user-provided specializtion std::regex_traits<char32_t> needs to be defined.
std::regex_traits<char32_t> is not provided by the standard. You must implement it yourself in order to use std::basic_regex<char32_t>.
Related
I'm trying to compile an example of some concept from cppreference with Clang on Mac and it fails. How can I fix the issue and compile the example?
Code:
#include <concepts>
#include <iostream>
template<std::regular T>
struct Single {
T value;
friend bool operator==(const Single&, const Single&) = default;
};
int main()
{
Single<int> myInt1{4};
Single<int> myInt2;
myInt2 = myInt1;
if (myInt1 == myInt2)
std::cout << "Equal\n";
std::cout << myInt1.value << ' ' << myInt2.value << '\n';
}
Terminal output:
% g++ -std=c++20 -o a a.cpp
a.cpp:4:15: error: no type named 'regular' in namespace 'std'
template<std::regular T>
~~~~~^
a.cpp:6:5: error: unknown type name 'T'
T value;
^
a.cpp:12:12: error: template argument for non-type template parameter must be an expression
Single<int> myInt1{4};
^~~
a.cpp:4:23: note: template parameter is declared here
template<std::regular T>
^
a.cpp:13:12: error: template argument for non-type template parameter must be an expression
Single<int> myInt2;
^~~
a.cpp:4:23: note: template parameter is declared here
template<std::regular T>
^
4 errors generated.
Compiler version:
% g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
What's interesting is that the example successfully compiles on GodBolt with lower CLang version (12.0.1)
How do I get boost::async to pass a function argument to the function it executes. My code is
#include <iostream>
// This is for the boos version
#include <boost/thread/future.hpp>
using boost::async;
// This is for the standard library version
//~ #include <future>
//~ using std::async;
int f(int x) {
std::cout << " in f " << x << std::endl;
return x+1;
}
int main() {
auto f_res = async(f,3);
std::cout << "f " << f_res.get() << std::endl;
return 0;
}
I compile with
g++ -std=c++14 -lboost_thread -lboost_system -lpthread test_async_boost.cc
, g++ version 5.3.0 and get many errors, complaining about the number of arguments async is willing to take:
test_async_boost_2.cc: In function 'int main()':
test_async_boost_2.cc:16:26: error: no matching function for call to 'async(int (&)(int), int)'
auto f_res = async(f,3);
^
In file included from test_async_boost_2.cc:3:0:
/usr/include/boost/thread/future.hpp:4035:3: note: candidate: template<class F> boost::unique_future<typename boost::result_of<F()>::type> boost::async(F&&)
async(BOOST_THREAD_FWD_REF(F) f) {
^
/usr/include/boost/thread/future.hpp:4035:3: note: template argument deduction/substitution failed:
test_async_boost_2.cc:16:26: note: candidate expects 1 argument, 2 provided
auto f_res = async(f,3);
^
In file included from test_async_boost_2.cc:3:0:
/usr/include/boost/thread/future.hpp:4018:3: note: candidate: template<class R> boost::unique_future<T> boost::async(R (*)())
async(R(*f)()) {
^
/usr/include/boost/thread/future.hpp:4018:3: note: template argument deduction/substitution failed:
test_async_boost_2.cc:16:26: note: candidate expects 0 arguments, 1 provided
auto f_res = async(f,3);
^
In file included from test_async_boost_2.cc:3:0:
/usr/include/boost/thread/future.hpp:3695:3: note: candidate: template<class F> boost::unique_future<typename boost::result_of<typename boost::decay<T>::type()>::type> boost::async(boost::launch, F&&)
async(launch policy, BOOST_THREAD_FWD_REF(F) f) {
^
/usr/include/boost/thread/future.hpp:3695:3: note: template argument deduction/substitution failed:
test_async_boost_2.cc:16:26: note: cannot convert 'f' (type 'int(int)') to type 'boost::launch'
auto f_res = async(f,3);
^
In file included from test_async_boost_2.cc:3:0:
/usr/include/boost/thread/future.hpp:3634:3: note: candidate: template<class R> boost::unique_future<T> boost::async(boost::launch, R (*)())
async(launch policy, R(*f)()) {
^
/usr/include/boost/thread/future.hpp:3634:3: note: template argument deduction/substitution failed:
test_async_boost_2.cc:16:26: note: cannot convert 'f' (type 'int(int)') to type 'boost::launch'
auto f_res = async(f,3);
^
If I switch the commenting in the #include directuves and the using lines, and compile with
g++ -std=c++14 test_async_boost_2.cc -lpthread
I get the desired output:
in f 3
f 4
How do I get boost::async to work with function arguments?
And: Where do I find the reference documentation of boos::async?
In order to pass a function with its arguments to the method accepting a function, you have to use std::bind or boost::bind.
I am currently using the cpprest API found at https://casablanca.codeplex.com/ for a simple RESTful API project.
This popular library uses Microsoft's PPLX framework to facilitate the async tasks.
I am currently encountering an issue in which code does not compile when a function returns an object of type pplx::task<SomeObj> and SomeObj has no default constructor. My understanding is that this code should be a valid as no default objects should be created.
Is there an error in my code or is this a bug?
Example Code:
#include <vector>
#include <string>
#include <cpprest/http_client.h>
class SomeSubObj {
public:
int a,b,c;
SomeSubObj(int a, int b, int c): a(a), b(b), c(c){}
};
class SomeObj {
public:
std::vector<SomeSubObj> subObjs;
SomeObj(std::string json){
// Populate from JSON...
subObjs.push_back(SomeSubObj(1,1,1));
subObjs.push_back(SomeSubObj(2,2,2));
subObjs.push_back(SomeSubObj(3,3,3));
}
};
pplx::task<SomeObj> doSomething(){
return pplx::task<std::string>([]() {
// Make a call out and get some json...
return std::string("{...}");
}).then([](std::string x) {
// Return a transformed object
return SomeObj("...");
});
}
int main()
{
doSomething();
return 0;
}
I am currently receiving the following output:
g++ -std=c++0x -Iboost_thread-mt -Iboost_atomic -Iboost_system -Icpprest -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Bug.d" -MT"src/Bug.d" -o "src/Bug.o" "../src/Bug.cpp"
In file included from ../src/Bug.cpp:4:
In file included from /usr/local/include/cpprest/http_client.h:44:
/usr/local/include/pplx/pplxtasks.h:2404:9: error: call to implicitly-deleted default constructor of '_ResultHolder<SomeObj>'
_Task_impl(_CancellationTokenState * _Ct, scheduler_ptr _Scheduler_arg)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2096:15: note: in instantiation of member function 'pplx::details::_Task_impl<SomeObj>::_Task_impl' requested here
__second_(_VSTD::forward<_Args2>(get<_I2>(__second_args))...)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2359:15: note: in instantiation of function template specialization 'std::__1::__libcpp_compressed_pair_imp<std::__1::allocator<pplx::details::_Task_impl<SomeObj> >, pplx::details::_Task_impl<SomeObj>, 1>::__libcpp_compressed_pair_imp<std::__1::allocator<pplx::details::_Task_impl<SomeObj> > &, pplx::details::_CancellationTokenState *&, pplx::scheduler_ptr &, 0, 0, 1>' requested here
: base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:3697:16: note: in instantiation of function template specialization 'std::__1::__compressed_pair<std::__1::allocator<pplx::details::_Task_impl<SomeObj> >, pplx::details::_Task_impl<SomeObj> >::__compressed_pair<std::__1::allocator<pplx::details::_Task_impl<SomeObj> > &, pplx::details::_CancellationTokenState *&, pplx::scheduler_ptr &>' requested here
: __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4271:26: note: in instantiation of function template specialization 'std::__1::__shared_ptr_emplace<pplx::details::_Task_impl<SomeObj>, std::__1::allocator<pplx::details::_Task_impl<SomeObj> > >::__shared_ptr_emplace<pplx::details::_CancellationTokenState *&, pplx::scheduler_ptr &>' requested here
::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4630:29: note: in instantiation of function template specialization 'std::__1::shared_ptr<pplx::details::_Task_impl<SomeObj> >::make_shared<pplx::details::_CancellationTokenState *&, pplx::scheduler_ptr &>' requested here
return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
^
/usr/local/include/pplx/pplxtasks.h:1429:103: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
static _Type _Make(_CancellationTokenState * _Ct, scheduler_ptr _Scheduler_arg) { return std::make_shared<_Task_impl<_ReturnType>>(_Ct, _Scheduler_arg); }
^
/usr/local/include/pplx/pplxtasks.h:3623:52: note: in instantiation of member function 'pplx::details::_Task_ptr<SomeObj>::_Make' requested here
_M_Impl = details::_Task_ptr<_ReturnType>::_Make(_Ct, _Scheduler);
^
/usr/local/include/pplx/pplxtasks.h:4138:27: note: in instantiation of member function 'pplx::task<SomeObj>::_CreateImpl' requested here
_ContinuationTask._CreateImpl(_PTokenState, _Scheduler);
^
/usr/local/include/pplx/pplxtasks.h:4101:16: note: in instantiation of function template specialization 'pplx::task<std::__1::basic_string<char> >::_ThenImpl<std::__1::basic_string<char>, <lambda at ../src/Bug.cpp:27:10> >' requested here
return _ThenImpl<_InternalReturnType, _Function>(_Func, _PTokenState, _TaskOptions.get_continuation_context(), _Scheduler, _CreationStack);
^
/usr/local/include/pplx/pplxtasks.h:3424:16: note: in instantiation of function template specialization 'pplx::task<std::__1::basic_string<char> >::_ThenImpl<std::__1::basic_string<char>, <lambda at ../src/Bug.cpp:27:10> >' requested here
return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
^
../src/Bug.cpp:27:5: note: in instantiation of function template specialization 'pplx::task<std::__1::basic_string<char> >::then<<lambda at ../src/Bug.cpp:27:10> >' requested here
}).then([](std::string x) {
^
/usr/local/include/pplx/pplxtasks.h:844:15: note: default constructor of '_ResultHolder<SomeObj>' is implicitly deleted because field '_Result' has no default constructor
_Type _Result;
^
1 error generated.
make: *** [src/Bug.o] Error 1
I tried to compile and run example of reset() function from http://www.cplusplus.com/reference/future/packaged_task/reset/:
$ cat task.cpp
// packaged_task::get_future
#include <iostream> // std::cout
#include <utility> // std::move
#include <future> // std::packaged_task, std::future
#include <thread> // std::thread
// a simple task:
int triple (int x) { return x*3; }
int main ()
{
std::packaged_task<int(int)> tsk (triple); // package task
std::future<int> fut = tsk.get_future();
std::thread (std::move(tsk),33).detach();
std::cout << "The triple of 33 is " << fut.get() << ".\n";
// re-use same task object:
tsk.reset();
fut = tsk.get_future();
std::thread(std::move(tsk),99).detach();
std::cout << "Thre triple of 99 is " << fut.get() << ".\n";
return 0;
}
but I got either compiler error or runtime error, depending on compiler used:
GCC:
$ g++ -o task -std=c++11 -I/opt/local/include task.cpp && ./task
The triple of 33 is 99.
terminate called after throwing an instance of 'std::future_error'
what(): No associated state
[1] 14850 abort ./task
CLANG:
$ clang++ -o task -std=c++11 -stdlib=libc++ -I/opt/local/include task.cpp && ./task
In file included from task.cpp:2:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/iostream:38:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/ios:216:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/__locale:15:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/string:439:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/algorithm:627:
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:1627:45: error: multiple overloads of 'address' instantiate to the same
signature 'const_pointer (const_reference) const noexcept'
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/type_traits:922:38: note: in instantiation of template class
'std::__1::allocator<int (int)>' requested here
: public integral_constant<bool, __is_empty(_Tp)> {};
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:1908:40: note: in instantiation of template class
'std::__1::is_empty<std::__1::allocator<int (int)> >' requested here
bool = is_empty<_T2>::value
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:1930:44: note: in instantiation of default argument for
'__libcpp_compressed_pair_switch<int (int), std::__1::allocator<int (int)>, false, false>' required here
template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:2298:15: note: in instantiation of default argument for
'__libcpp_compressed_pair_imp<int (int), std::__1::allocator<int (int)> >' required here
: private __libcpp_compressed_pair_imp<_T1, _T2>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:1770:36: note: in instantiation of template class
'std::__1::__compressed_pair<int (int), std::__1::allocator<int (int)> >' requested here
__compressed_pair<_Fp, _Alloc> __f_;
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:1877:9: note: in instantiation of template class
'std::__1::__packaged_task_func<int (int), std::__1::allocator<int (int)>, int (int)>' requested here
if (sizeof(_FF) <= sizeof(__buf_))
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:2026:45: note: in instantiation of function template specialization
'std::__1::__packaged_task_function<int (int)>::__packaged_task_function<int (&)(int)>' requested here
explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
^
task.cpp:12:32: note: in instantiation of function template specialization 'std::__1::packaged_task<int
(int)>::packaged_task<int (&)(int), void>' requested here
std::packaged_task<int(int)> tsk (triple); // package task
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:1625:39: note: previous declaration is here
_LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:2121:9: error: data member instantiated with function type 'int (int)'
_T1 __first_;
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:2298:15: note: in instantiation of template class
'std::__1::__libcpp_compressed_pair_imp<int (int), std::__1::allocator<int (int)>, 2>' requested here
: private __libcpp_compressed_pair_imp<_T1, _T2>
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:1770:36: note: in instantiation of template class
'std::__1::__compressed_pair<int (int), std::__1::allocator<int (int)> >' requested here
__compressed_pair<_Fp, _Alloc> __f_;
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:1877:9: note: in instantiation of template class
'std::__1::__packaged_task_func<int (int), std::__1::allocator<int (int)>, int (int)>' requested here
if (sizeof(_FF) <= sizeof(__buf_))
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:2026:45: note: in instantiation of function template specialization
'std::__1::__packaged_task_function<int (int)>::__packaged_task_function<int (&)(int)>' requested here
explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
^
task.cpp:12:32: note: in instantiation of function template specialization 'std::__1::packaged_task<int
(int)>::packaged_task<int (&)(int), void>' requested here
std::packaged_task<int(int)> tsk (triple); // package task
^
2 errors generated.
I'm using OSX Maverics and compilers:
$ g++ --version
g++ (MacPorts gcc48 4.8.2_0) 4.8.2
$ clang++ --version
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
Could someone please help me?
GCC is correct:
std::thread (std::move(tsk),33).detach(); // 1
//...
tsk.reset(); // 2
After (1), tsk has no more state (per move constructor of packaged_task)
At (2), reset() is required to throw the no_state std::future_error
clang had a bug, as pointed out in the comments.
I am trying to use boost::future .then() functionality.
The snippet is taken from Boost 1.54.0 thread synchronisation documentation
#include <string>
#include <boost/thread/future.hpp>
int main() {
boost::future<int> f1 = boost::async([]() { return 123; });
boost::future<std::string> f2 = f1.then([](boost::future<int> f)->std::string {
int x = f.get();
return ("Done" + std::to_string(x));
});
}
Setup :
Ubuntu 13.04
g++ version g++ (Ubuntu 4.8.1-2ubuntu1~13.04) 4.8.1
Boost version 1.54.0
command line :
g++ then_test.cc -std=c++0x -DBOOST_THREAD_VERSION=4 -I /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost -L /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/stage/lib -static -lboost_thread-mt -lboost_date_time-mt -lboost_system-mt -lpthread
Error:
g++ then_test.cc -std=c++0x -DBOOST_THREAD_VERSION=4 -I /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost -L /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/stage/lib -static -lboost_thread-mt -lboost_date_time-mt -lboost_system-mt -lpthread
then_test.cc: In function ‘int main()’:
then_test.cc:10:44: error: no matching function for call to ‘boost::future<int>::then(main()::__lambda1)’
});
^
then_test.cc:10:44: note: candidates are:
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1598:9: note: template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(F&&) [with F = F; R = int]
then(BOOST_THREAD_FWD_REF(F) func);
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1598:9: note: template argument deduction/substitution failed:
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp: In substitution of ‘template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(F&&) [with F = F; R = int] [with F = main()::__lambda1]’:
then_test.cc:10:44: required from here
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:62:29: error: no type named ‘type’ in ‘struct boost::result_of<main()::__lambda1(boost::future<int>&)>’
#define BOOST_THREAD_FUTURE future
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:3840:3: note: in expansion of macro ‘BOOST_THREAD_FUTURE’
BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func)
^
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1601:9: note: template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(boost::launch, F&&) [with F = F; R = int]
then(launch policy, BOOST_THREAD_FWD_REF(F) func);
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1601:9: note: template argument deduction/substitution failed:
then_test.cc:10:44: note: cannot convert ‘<lambda closure object>main()::__lambda1{}’ (type ‘main()::__lambda1’) to type ‘boost::launch’
});
Please let me know if I am missing something here.
Passing future by reference to .then() fixes the compilation issue on gcc 4.8 & clang.
For windows and gcc 4.7 we additionally need to define BOOST_RESULT_OF_USE_DECLTYPE. (as per Xeo's comment). For gcc 4.8 & clang it seems available already.
boost::future<std::string> f2 = f1.then([](boost::future<int>& f)->std::string {
^