Andres Jaan Tack
Andres Jaan Tack

Reputation: 23024

Why don't I need to std::move to a std::bind'ed function?

Let's say I have a function, taking an rvalue reference:

void whatever (std::unique_ptr<int>&&) {
    // Nothing!
}

... and I bind its one parameter to a placeholder.

auto f = std::bind(&whatever, _1);

I tried the invocations like this, and the result is the opposite of what I was expecting.

std::unique_ptr<int> nothing;
f(std::move(nothing));  // Fails to compile!
f(nothing);             // Works, but seems wrong!

Is this a compiler bug? Or, is the working invocation unsafe code? Or why is it that I don't have to std::move this pointer into the bound function?

The compile error with gcc4.4, by the way, is:

test.cxx:14: error: no match for call to '(std::_Bind<void (*(std::_Placeholder<1>))(std::unique_ptr<int, std::default_delete<int> >&&)>) (std::unique_ptr<int, std::default_delete<int> >)'

Upvotes: 1

Views: 393

Answers (1)

Howard Hinnant
Howard Hinnant

Reputation: 218860

I get just the opposite results when using libc++.

std::unique_ptr<int> nothing;
f(std::move(nothing));  // Works!
f(nothing);             // Fails to compile!

I believe this is a gcc4.4 bug. [func.bind.bind]/p10/b3 describes this case:

  • if the value j of is_placeholder<TiD>::value is not zero, the argument is std::forward<Uj(uj)> and its type Vi is Uj&&;

This may be fixed in a more recent gcc (I have no idea).

Upvotes: 5

Related Questions