【问题标题】:Is there a mutable version of std::bind?是否有 std::bind 的可变版本?
【发布时间】:2017-10-27 09:09:57
【问题描述】:

我正在尝试在 std::unique_ptrstd::bindstd::move。生成的函数对象似乎是不可变的,因此在调用函子时不可能执行移动。

我怀疑这是因为 lambda 在默认情况下是不可变的,原因相同 - 每次调用它们都应该做同样的事情。但是在某些情况下它们需要是可变的,这就是我们使用 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,我可以将函数调用包装在可变 lambda 中。但至少对我个人而言,bind 在这种情况下看起来更干净、更简单。

我知道调用可变 lambda 两次会导致未定义的行为,因为我会再次从一个已经移动的指针移动。但就我而言,我知道函子只会被调用一次。

有没有办法可以使用std::bind 来做到这一点?有bind_mutable 之类的吗?如果没有,我应该如何自己写?

【问题讨论】:

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


【解决方案1】:

但至少对我个人而言,bind 在这种情况下看起来更干净、更简单。

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

在这种情况下,它可能看起来更简单、更干净,但不建议这样做。

写作中...

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

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

【讨论】:

  • [&amp;ptr]() { foo(std::move(ptr)); }(); 顺便说一句就够了。
  • &amp;ptr 语法的缺点是您的 lambda 无法复制/移出当前堆栈上下文。 C++14 解决了这个问题。
猜你喜欢
  • 2016-12-01
  • 2016-04-09
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 2014-12-08
  • 1970-01-01
  • 2016-06-11
  • 2017-08-21
相关资源
最近更新 更多