c++ - gcc shared_ptr复制赋值实现

标签 c++ c++11 gcc shared-ptr libstdc++

我正在扫描 GCC 5 中的 shared_ptr 实现,我看到了以下内容:

  __shared_ptr&
  operator=(__shared_ptr&& __r) noexcept
  {
    __shared_ptr(std::move(__r)).swap(*this);
    return *this;
  }

我的问题是为什么在交换之前 临时的额外移动构造?我假设编译会消除任何额外的开销——但为什么不直接调用 __r.swap(*this)?有没有我遗漏的一些聪明的副作用?

我看到类中的其他函数也使用相同的模式实现,我能理解接受 const 引用但接受右值引用的情况吗?

最佳答案

首先,这就是标准所说的,GCC 只是严格遵守。

这样赋值运算符就有一个后置条件 __r.empty() 你的建议无法实现,所以按照你的建议实现它会对标准所说的产生不同的影响,并且所以将是不合格的。

即这个断言成立:

auto p1 = std::make_shared<int>(1);
auto p2 = std::make_shared<int>(2);
p1 = std::move(p2);
assert( !p2 );

“聪明的副作用”是你创建了一个新的empty shared_ptr,它在交换后最终保留了 *this 的旧值,然后退出的范围。这意味着 *this 的旧值不会在 __r 中结束。

关于c++ - gcc shared_ptr复制赋值实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34277238/

相关文章:

C++数学函数生成

c++ - 使用命名捕获找出给定正则表达式中命名组的所有名称

c++ - 使用 C++11 复制构造 boost::shared_ptr 时出错

c++ - 对可删除对象的非拥有引用

c++ - 查看类型是否可调用

c++ - g++ 与 lib 有未引用的函数错误

multithreading - timed_mutex 不会在 Cygwin 4.8.2 ('timed_mutex' 下编译,命名空间 'std' 没有命名类型)

c++ - move 构造函数是否必须调用 std::move()?

c++ - 将指针用于条件 while/for 循环会在编译时出错

c++ - 使用别名引用匿名结构会导致错误