std :: async使用绑定到lambda的右值引用 [英] std::async using an rvalue reference bound to a 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 $ c $
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屋!