std :: async使用绑定到lambda的右值引用 [英] std::async using an rvalue reference bound to a lambda

查看:1039
本文介绍了std :: async使用绑定到lambda的右值引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 std :: bind 绑定一个值到lambda的右值引用,但是当我把它引入 std :: async 调用:(

I'm trying to bind an rvalue reference to a lambda using std::bind, but I have issues when I throw that into a std::async call: (source)

auto lambda = [] (std::string&& message) {
    std::cout << message << std::endl;
};
auto bound = std::bind(lambda, std::string{"hello world"});
auto future = std::async(bound); // Compiler error here
future.get()

m不太确定如何解释:

This issues a compiler error I'm not really sure how to interpret:


错误:没有类型命名为'type'在'std :: result_of(std :: basic_string )>&()>'

error: no type named 'type' in 'class std::result_of(std::basic_string)>&()>'

这里发生了什么?有趣的是,轻微的修改确实编译并按预期工作。如果我将 std :: string {hello world} 更改为c字符串文字,一切正常:(资源

What's going on here? Interestingly, a slight modification does compile and work as expected. If I change std::string{"hello world"} to a c-string literal, everything works fine: (source)

auto lambda = [] (std::string&& message) {
    std::cout << message << std::endl;
};
auto bound = std::bind(lambda, "hello world");
auto future = std::async(bound);
future.get(); // Prints "hello world" as expected

为什么这样工作, p>

Why does this work but not the first example?

推荐答案

std :: bind c $ c> std :: string 参数,并将其传递给lambda。但是编译失败,因为lambda需要一个rvalue参数,而 bind 传递它将是一个左值。你可以得到这个工作,如果你绑定移动参数,但这需要非常丑陋的转换消歧因为 std :: move 是一个重载函数)。

std::bind is going to make a copy of the std::string argument and pass that to the lambda. But that fails to compile because the lambda requires an rvalue argument, while what bind passes it will be an lvalue. You could get this to work if you get bind to move the argument, but this requires extremely ugly casting for disambiguation (because std::move is an overloaded function).

auto bound = std::bind(lambda, std::bind(static_cast<std::string&&(*)(std::string&)>(std::move),
                                         std::string{"hello world"}));

现场演示

您当然可以编写您自己的 move

You could, of course, write your own version of move that is not overloaded, and avoid that cast.

第二种情况的原因是当 bind 通过 char const * 到lambda,隐式创建一个右值 std :: string temporary。

The second case works because when bind passes the char const * to the lambda, an rvalue std::string temporary is created implicitly.

为了解释你看到的错误信息,在 std :: async std :: result_of 正被调用以确定函数调用表达式的返回类型。但是,由于上述原因,该调用表达式无效,因此 result_of 正在SFINAE中出来(这是一个C ++ 14的变化)。因此,错误错误:在'std :: result_of< ...>'中没有名为'type'的类型。

To explain the error message you're seeing, somewhere within the innards of std::async, std::result_of is being invoked to determine the return type of the function call expression. However, because that call expression is invalid due to the reasons explained above, result_of is being SFINAE'd out (this is a C++14 change). Hence the error error: no type named 'type' in 'class std::result_of<...>'.

这篇关于std :: async使用绑定到lambda的右值引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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