std::bind 有可变版本吗?
Is there a mutable version of std::bind?
我正在尝试 std::bind
std::move
std::unique_ptr
。生成的函数对象似乎是不可变的,因此在调用仿函数时不可能执行移动。
我怀疑这是因为默认情况下 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
之类的?如果没有,我该如何自己写呢?
However at least to me personally bind looks much cleaner and simpler in this case.
不要在 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)); }();
...是解决这个问题的正确方法。
我正在尝试 std::bind
std::move
std::unique_ptr
。生成的函数对象似乎是不可变的,因此在调用仿函数时不可能执行移动。
我怀疑这是因为默认情况下 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
之类的?如果没有,我该如何自己写呢?
However at least to me personally bind looks much cleaner and simpler in this case.
不要在 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)); }();
...是解决这个问题的正确方法。