可以将std :: async与模板功能一起使用 [英] Can std::async be use with template functions

查看:176
本文介绍了可以将std :: async与模板功能一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

std::async 是否适合使用模板功能?我已尝试对 std::reverse 作罢,因为异步任务bu出现编译时错误.

我尝试使用更简单的函数(foo和bar),发现只有非模板函数在起作用.

#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();
}

编译器错误如下:

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>’

但是,当我手动指定模板实例时,例如std::async(std::reverse<std::string::iterator>, str.begin(), str.end()),它就会通过.

这是编译器错误(GCC 4.6.3)还是定义明确的行为?

解决方案

可以,但是调用有点不同:

auto result_reverse = std::async([&str]() {
        std::reverse(str.begin(), str.end());
    });

这是因为std::reverse()不是函数,而是当作为函数调用时变成函数的函数模板.

上面的方法将字符串的副本反向并丢弃结果.要通过引用传递字符串,应将lambda表达式更改为以[&str]()开头.

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?

解决方案

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]().

这篇关于可以将std :: async与模板功能一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆