Difference between std :: async and std :: bind when packing rvalue reference lambda

Inspired by this comment about binding lambdas with rvalue link parameters directly to std::async , binding rvalue to lambda via std::async compiles and runs as expected: ( live example )

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

Using std::bind , however, raises a compiler error: ( live example )

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

This is because std::bind saves the message as an lvalue, so when it passes it to lambda, the argument no longer matches the parameter.

I read that std::async internally uses std::bind since it leaves with the rvalue link parameters when std::bind not? Is there a certain part of the standard that requires this behavior, or does it depend on the compiler?

+8
c ++ lambda c ++ 11 rvalue-reference stdbind
source share
1 answer

I read that std::async internally uses std::bind , since this leaves with rvalue if std::bind does not work?

It does not use bind internally. (Or rather, he could not help but experience some kind of epic distortion, similar to what was in @Praetorian's answer in this question , and it is much easier to just write something separately).

It is usually implemented using a somewhat bind mechanism, but it is much simpler because it does not need to handle all kinds of weird bind handle things (nested bind s, placeholders, dropping extra arguments, etc.)

Is there a specific part of the standard that requires this behavior, or does it depend on the compiler?

Required by standard. The bind specification is ridiculously tight, but requires simple, related arguments to be passed as lvalues ​​([func.bind.bind] / p10, bullet 4).

async is specified to invoke INVOKE (DECAY_COPY (std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) , and DECAY_COPY always returns rvalue.

+4
source share

All Articles