Work-around for missing "move-capture" syntax in C++0x

S

SG

Hi!

This is not a question but more of an observation. As you might
already know, C++0x's lambda syntax only allows capturing by reference
and capturing by value (copying). And if I remember correctly, there
is no requirement for closure types to have a move constructor. I
already saw code examples involving lambdas and shared_ptr where
shared_ptr was only used because it wasn't possible to "move-capture"
a unique_ptr. But the std::bind facility is quite flexible with
respect to move-only types. With std::bind we can turn the following,
non-working code

void foo() {
unique_ptr<big> p (new big);
// ... set up *p
invoke_later([=]{ // <-- Oops! unique_ptr cannot be copied.
// work on *p
});
}

into

void foo() {
unique_ptr<big> p (new big);
// ... set up *p
invoke_later(bind([](unique_ptr<big> const& p){
// work on *p
},move(p)));
}

and have it work without the need for std::shared_ptr. This extends to
all other move-enabled types. For example, if you want to move a
string into a function object, you have to use std::bind for this
because C++0x doesn't offer a "move-capture" syntax. IMHO, it's a
shame that we have to do that. But at least this seems like a decent
work-around. (untested)

Cheers!
SG
 
B

Bo Persson

SG said:
Hi!

This is not a question but more of an observation. As you might
already know, C++0x's lambda syntax only allows capturing by
reference and capturing by value (copying). And if I remember
correctly, there is no requirement for closure types to have a move
constructor. I already saw code examples involving lambdas and
shared_ptr where shared_ptr was only used because it wasn't
possible to "move-capture" a unique_ptr. But the std::bind facility
is quite flexible with respect to move-only types. With std::bind
we can turn the following, non-working code

void foo() {
unique_ptr<big> p (new big);
// ... set up *p
invoke_later([=]{ // <-- Oops! unique_ptr cannot be copied.
// work on *p
});
}

Isn't that a good thing? Why use a unique_ptr if you really want to
have copies?


Bo Persson
 
S

SG

SG said:
   void foo() {
       unique_ptr<big> p (new big);
       // ... set up *p
       invoke_later([=]{ // <-- Oops! unique_ptr cannot be copied.
           // work on *p
       });
   }

Isn't that a good thing? Why use a unique_ptr if you really want to
have copies?

Who says I'm interested in copying it? I just want to be able to move
things into a lambda function object. In other words, C++0x lacks a
std::move-equivalent of the capture-clause. This bugged me for quite a
while and I even informally proposed a syntax for that:

template<class Fun>
void invoke_later(Fun && f)
{
// jobqueue could be a vector<function<void()>>
jobqueue.emplace_back(std::forward<Fun>(f));
}

void foo() {
unique_ptr<big> p (new big);
// ... set up *p
invoke_later([-p]{ // "move-capture"
// work on *p
});
}

But the chance that something like this is going to make it into C++0x
this late in the game is probably zero.

On the upside, we can work around this lacking "move-capture" via
std::bind. It may or may be obvious to most. This std::bind work-
around just dawned on me and I thought it would be worth sharing.

Cheers!
SG
 
S

SG

    template<class Fun>
    void invoke_later(Fun && f)
    {
        // jobqueue could be a vector<function<void()>>
        jobqueue.emplace_back(std::forward<Fun>(f));
    }

Strike that. I think std::function requires the function objects to be
copyable. But std::thread and std::async don't and one could easily
write a type-erasing wrapper that allows move-only function objects to
be stored for later use or execution in another thread (i.e. a GUI
event processing thread).

Cheers!
SG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top