c++ - std::bind 和/或 std::forward 的语义

标签 c++ c++11 parameter-passing variadic-functions stdbind

我发现以下代码无法编译非常令人困惑

#include <functional>

class Mountain {
public:
  Mountain() {}
  Mountain(const Mountain&) = delete;
  Mountain(Mountain&&) = delete;
  ~Mountain() {}
};

int main () {
  Mountain everest;
  // shouldn't the follwing rvalues be semantically equivalent?
  int i = ([](const Mountain& c) { return 1; })(everest);
  int j = (std::bind([](const Mountain& c) {return 1;},everest))();
  return 0;
}
编译错误是:
$ g++ -std=c++20 test.cpp -o test
In file included from test.cpp:1:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/functional:486:26: error: no
      matching constructor for initialization of 'tuple<Mountain>'
        : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
                                ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/functional:788:14: note: in
      instantiation of function template specialization 'std::_Bind<(lambda at test.cpp:14:22)
      (Mountain)>::_Bind<Mountain &>' requested here
      return typename __helper_type::type(std::forward<_Func>(__f),
             ^
test.cpp:14:17: note: in instantiation of function template specialization 'std::bind<(lambda at
      test.cpp:14:22), Mountain &>' requested here
  int j = (std::bind([](const Mountain& c) {return 1;}, everest))();
                ^
...
所以std::bind偷偷尝试复制everest即使 lambda 只想引用它。我是在遇到一个没人关心的奇怪边缘情况(例如,总是可以通过 lambda 捕获对 everest 的引用)还是有理由?如果理由是 bind 可以保护我在 everest 之后不调用 lambda被破坏了,是否有一个不安全的绑定(bind)版本不会这样做?

最佳答案

是的, std::bind 的论据将被复制(或移动)。

The arguments to bind are copied or moved, and are never passed by reference unless wrapped in std::ref or std::cref.


您可以使用 std::cref (或 std::ref )代替。例如。
int j = (std::bind([](const Mountain& c) {return 1;}, std::cref(everest)))();
//                                                    ^^^^^^^^^^       ^
LIVE

关于c++ - std::bind 和/或 std::forward 的语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67601645/

相关文章:

c++ - 使用 STL 算法重写的指针的循环示例,没有循环?

c++ - 在 C++ 中追加不同的字段

c++ - 使用代理对象延迟更新与 "Avoid unnamed objects with custom construction and destruction"

c++ - 如何在自己的类中使用默认比较器?

c++ - std::condition_variable::notify_one() 不唤醒等待线程

C++:ios::out 是用新文件替换文件还是破坏文件内容?

c++ - 优化具有两个条件的数组元素的比较; C++ 抽象机制?

vb.net - 从 VB6 转换为 VB.Net 后字符串默认参数值问题

c# - 从 C# 调用 C++/CLI(不带 out 参数)

java - 将对象数组传递给方法