Can std::async be use with template functions
asynchronous, c++, c++11, std, templates
Solution
It can, but the invocation is a bit different:
auto result_reverse = std::async([&str]() {
std::reverse(str.begin(), str.end());
});
This is because `std::reverse()` is not a function, rather a function template that turns into a function when it is invoked as a function.
The above reverses a copy of the string and throws away the result. To pass the string by reference the lambda expression should be changed to start with `[&str]()`.
Problem
Is `std::async` supose to work with template function? I've tried to lauch `std::reverse` as an asynchronous task bu got compile-time error. I've tried to use simpler functions (foo and bar) and discover that only the non-template-function are working. ``` #include <algorithm> #include <future> #include <string> void foo(std::string::iterator first, std::string::iterator last) { } template<class BidirectionalIterator> void bar(BidirectionalIterator first, BidirectionalIterator last) { } int main() { std::string str = "Lorem ipsum, dolor sit amet"; auto result_reverse = std::async(std::reverse, str.begin(), str.end()); // Compile-time error auto result_foo = std::async(foo, str.begin(), str.end()); auto result_bar = std::async(bar, str.begin(), str.end()); // Compile-time error result_reverse.get(); result_foo.get(); result_bar.get(); } ``` The compiler error is as follow: ``` main.cpp: In function ‘int main()’: main.cpp:18:71: erreur: no matching function for call to ‘async(<unresolved overloaded function type>, std::basic_string<char>::iterator, std::basic_string<char>::iterator)’ main.cpp:18:71: note: candidates are: /usr/include/c++/4.6/future:1355:5: note: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) /usr/include/c++/4.6/future:1378:5: note: template<class _Fn, class ... _Args> typename std::__async_sfinae_helper<typename std::decay<_Functor>::type, _Fn, _Args ...>::type std::async(_Fn&&, _Args&& ...) main.cpp:18:71: erreur: unable to deduce ‘auto’ from ‘<expression error>’ main.cpp:20:62: erreur: no matching function for call to ‘async(<unresolved overloaded function type>, std::basic_string<char>::iterator, std::basic_string<char>::iterator)’ main.cpp:20:62: note: candidates are: /usr/include/c++/4.6/future:1355:5: note: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) /usr/include/c++/4.6/future:1378:5: note: template<class _Fn, class ... _Args> typename std::__async_sfinae_helper<typename std::decay<_Functor>::type, _Fn, _Args ...>::type std::async(_Fn&&, _Args&& ...) main.cpp:20:62: erreur: unable to deduce ‘auto’ from ‘<expression error>’ ``` However, it pass when I manually specify the template instanciation, such as `std::async(std::reverse<std::string::iterator>, str.begin(), str.end())`. Is this a compiler bug (GCC 4.6.3) or a well defined behaviour?