为什么std::future<T>和std::shared_future<T>不提供成员swap()?

Why do std::future<T> and std::shared_future<T> not provide member swap()?

C++标准库中的各种classes都有成员交换函数,包括一些多态的classes,如std::basic_ios<CharT>。模板 class std::shared_future<T> 显然是值类型,而 std::future<T> 是仅移动值类型。有什么特别的原因,他们不提供swap()成员函数吗?

在 C++11 std::move 支持之前,成员交换是一个巨大的性能提升。例如,您可以通过这种方式将一个矢量移动到另一个位置。它也用于 vector 调整大小,这意味着插入向量向量并不是完全的性能自杀。

std::move 到达 C++11 之后,std::swap 的默认实现有许多有时为空的类型:

template<class T>
void swap( T& lhs, T& rhs ) {
  auto tmp = std::move(rhs);
  rhs = std::move(lhs);
  lhs = std::move(tmp);
}

基本上和自定义编写的一样快。

具有 swap 个成员的现有类型不太可能丢失它们(至少立即丢失)。但是,扩展新类型的 API 应该是合理的。

如果 std::future 基本上是 std::unique_ptr< future_impl > 的包装器,那么上面的代码将需要 4 次指针读取、3 次指针写入和一个分支。内联它的优化编译器1 可以将其减少到 2 个指针读取和 2 个指针写入(例如使用 SSA2),这是优化的 .swap 成员函数可以做什么。


1 所以它知道对 lhsrhs 的中间访问永远不会发生,因此 tmp 的存在可以被消除为-if 一旦它证明 tmp 是空的,因此有一个空操作 dtor。

2 Static single assignment,您可以在其中分解程序,以便对原语的每次赋值都会创建一个全新的变量(带有元数据)。然后证明该变量的属性,并消除多余的。