我正在尝试使用来将右值引用绑定到lambda std::bind
,但是当我将其放入std::async
调用中时遇到问题:(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()
这发出了一个编译器错误,我不确定如何解释:
错误:“类std :: result_of(std :: basic_string)>&()>中没有名为“ type”的类型
这里发生了什么?有趣的是,稍加修改便可以按预期进行编译和运行。如果我更改std::string{"hello world"}
为C字符串文字,则一切正常:(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
为什么这样做有效,但第一个示例无效?
std::bind
将复制该std::string
参数并将其传递给lambda。但这无法编译,因为lambda需要一个rvalue参数,而bind
传递给它的将是一个lvalue。如果您bind
要讨论move
该参数,则可以使它起作用,但这需要非常难看的转换才能消除歧义(因为这std::move
是一个重载函数)。
auto bound = std::bind(lambda, std::bind(static_cast<std::string&&(*)(std::string&)>(std::move),
std::string{"hello world"}));
当然,您可以编写自己的move
未超载版本,并避免进行强制转换。
第二种情况有效,因为bind
将传递char const *
给lambda时,std::string
会隐式创建一个右值临时值。
为了解释您所看到的错误消息std::async
,std::result_of
正在调用的内幕中的某处,以确定函数调用表达式的返回类型。但是,由于上述原因,该调用表达式无效,因此result_of
已被SFINAE删除(这是C ++ 14的更改)。因此错误error: no type named 'type' in 'class std::result_of<...>'
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句