是否有std :: bind的可变版本?

时间:2017-10-27 09:09:58

标签: c++ c++11 lambda immutability

我正试图在std::bindstd::move std::unique_ptr。结果函数对象似乎是不可变的,因此在调用仿函数时不可能执行移动。

我怀疑这是因为默认情况下lambdas不可变的原因相同 - 每次调用它们都应该做同样的事情。但是,有些情况下它们需要是可变的,这就是我们拥有mutable关键字的原因。

void foo(std::unique_ptr<int>&& ptr)
{
    cout << *ptr << endl;
}

int main()
{
    std::unique_ptr<int> ptr = std::make_unique<int>(123);
    std::bind(foo, std::move(ptr))();             // Doesn't compile
    [&ptr]() { foo(std::move(ptr)); }();          // Equivalent, doesn't compile
    [&ptr]() mutable { foo(std::move(ptr)); }();  // Compiles
    return 0;
}

使用bind的Instad我可以在一个可变的lambda中包装一个函数调用。但是至少对我个人而言bind在这种情况下看起来更清晰,更简单。

据我所知,两次调用mutable lambda会导致未定义的行为,因为我将从已经移动的指针再次移动。但就我而言,我知道仿函数只会被调用一次。

我有没有办法std::bind这样做?有bind_mutable种吗?如果没有,我该如何自己写呢?

1 个答案:

答案 0 :(得分:2)

  

但至少在我看来,亲自绑定看起来更简洁,更简单。

不要在C ++ 11中使用std::bind。请改用lambdas。 std::bind有几个问题excellently explained in this talk by Stephan T. Lavavej “functional: What's New, And Proper Usage"

screenshot from talk

在这种情况下看起来可能更简单,更清洁,但不建议这样做。

...书写

[&ptr]{ foo(std::move(ptr)); }(); 

...是解决这个问题的正确方法。