0

While reading through the doc: https://isocpp.org/wiki/faq/cpp14-language#lambda-captures,

    auto u = make_unique<some_type>( some, parameters );  // a unique_ptr is move-only
    go.run( [ u=move(u) ] { do_something_with( u ); } ); // move the unique_ptr into the lambda

When we pass u in do_something_with(), shall we use std::move(u)? I meant do_something_with(std::move(u)) given u is still move-only as unique_ptr though its captured in lambda.

Thanks for the help!

Note: I came across this: https://stackoverflow.com/a/16968463/13097437 but it simply quotes the example which I think its buggy above.

idoay
  • 21
  • 2

2 Answers2

3

How you pass u to do_something_with is independent of whether or not a lambda is being used. If do_something_with is declared as

void do_something_with(std::unique_ptr<some_class> u)

that is, it takes its parameter by value, then yes, you would need to move the caller's pointer into the function call. On the other hand, if do_something_with is declared as

void do_something_with(std::unique_ptr<some_class> & u)

that is, it takes its parameter by reference, then no, there is no point in trying to move the caller's pointer.

Given that both possibilities are valid, the example went with the one that yielded simpler code. Don't read too much into that.

Personally, I would think a call like do_something_with(*u) (pass the pointed-to-object) is more likely than passing the pointer directly, but of course one size does not fit all. The example from the C++ FAQ is about as simple as it gets while keeping a descriptive function name.

JaMiT
  • 14,422
  • 4
  • 15
  • 31
0
auto u = make_unique<some_type>( some, parameters );  // a unique_ptr is move-only
go.run( [ u=move(u) ] { do_something_with( u ); } ); // move the unique_ptr into the lambda

I would do

auto u = make_unique<some_type>( some, parameters );  // a unique_ptr is move-only
go.run( [ u=move(u) ]()mutable { do_something_with( std::move(u) ); } ); // move the unique_ptr into the lambda

or

auto u = make_unique<some_type>( some, parameters );  // a unique_ptr is move-only
go.run( [ u=move(u) ] { do_something_with( u.get() ); } );

depending on if I am going to transfer ownership or not.

But this is just quality. If do something with takes its argument by const reference, the code compiles as is.

I would generally advise against a const reference unique ptr argument however. It is like passing a vector by const reference; you are needlessly constraining the type of argument with implementation details (the exact class used to store the pointer, or the contiguous buffer) for little reason.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524