c++11 - std::move 与 lambda 中的 std::shared_ptr

标签 c++11 lambda c++14 shared-ptr move

在 lambda 中 move std::shared_ptr 时,我遇到了一个奇怪的问题。我不确定这是否是一个错误,因为我可以使用 g++ v6.3 和 clang++ v3.9 重现。

当我编译并运行以下程序时:

#include <iostream>
#include <memory>

void f(std::shared_ptr<int> ptr) {
  std::cout << 3 << " " << ptr.get() << std::endl;
}

int main() {
  auto ptr = std::make_shared<int>(42);
  std::cout << 1 << " " << ptr.get() << std::endl;
#ifdef LAMBDA
  auto lambda = [ptr]() {
#endif
    f(std::move(ptr));
    std::cout << 2 << " " << ptr.get() << std::endl;
#ifdef LAMBDA
  };
  lambda();
#endif
}

使用命令c++ -std=c++14 -o test main.cpp && ./test 会产生类似的结果

1 0x55a49e601c30 1
3 0x55a49e601c30 1
2 0 0

但是,将编译命令更改为 c++ -std=c++14 -o test main.cpp -DLAMBDA 会使执行打印一些我无法解释的内容:

1 0x55a49e601c30 1
3 0x55a49e601c30 3
2 0x55a49e601c30 2

因此,看起来 std::move(move) 在 lambda 内部执行时,实际上并不会导致 shared_ptr 被 move ,也不会防止其引用计数器增加。

同样,我可以使用 clang++ 和 g++ 重现这一点。

这怎么可能?

最佳答案

捕获的变量ptr lambda 中的默认值是 const,即 ptr 的类型是 const std::shared_ptr<int> .

std::move无法移出 const 对象,因此会创建一个副本。

如果你真的想 move 它,ptr必须允许可变:

auto lambda = [ptr]() mutable {
//                    ^~~~~~~

关于c++11 - std::move 与 lambda 中的 std::shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43319352/

相关文章:

构造函数中的 C++14 constexpr union 条件初始化

c++ - 自动返回类型匹配 void

c++ - 函数 C++ 中的静态指针变量

c++ - 在 C++ 中将数据加载到内存中

c++ - 文字运算符模板 : why not string?

c++ - vector 元组并向后推

c++ - C++ 中更宽松的抛出说明符

c# - 具有聚合函数的 lambda 表达式

java - 将 java Stream 转换为 Set

python - 在python中将函数作为参数传递