Boost C++ 库

...世界上最受尊敬和专家设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

PrevUpHomeNext

swap(交换)

头文件 <boost/core/invoke_swap.hpp>
简介
基本原理
异常安全性
要求
可移植性
致谢

作者

  • Niels Dekker
  • Joseph Gauterin
  • Steven Watanabe
  • Eric Niebler

template<class T> void invoke_swap(T& left, T& right) noexcept(见下文);

模板函数 boost::core::invoke_swap 允许交换两个变量的值,使用依赖于参数的查找来选择特化的 swap 函数(如果可用)。如果没有可用的特化 swap 函数,则使用 std::swap

泛型 std::swap 函数要求要交换的元素是可赋值和可复制构造的。它通常使用一个复制构造和两个赋值来实现(C++11 将复制操作替换为移动)——这通常既不必要地限制性,也不必要地缓慢。此外,在泛型 swap 实现只提供基本保证的情况下,特化的 swap 函数通常能够提供无抛出异常保证(并且在可能的情况下这样做被认为是最佳实践[1])。

在这种情况下,使用依赖于参数的查找的替代方法是为每个需要特化 swap 的类型提供 std::swap 的模板特化。虽然这是合法的 C++,但没有 Boost 库使用这种方法,而许多 Boost 库在其自己的命名空间中提供了特化的 swap 函数。

boost::core::invoke_swap 还支持交换内置数组。请注意,std::swap 最初并没有这样做,但是向 C++ 标准委员会提出了为内置数组添加 std::swap 重载的请求,该请求已被接受[2]

boost::core::invoke_swap 提供与所使用的底层 swap 函数相同的异常保证,但有一个例外;对于类型为 T[n] 的数组,其中 n > 1 并且 T 的底层 swap 函数提供强异常保证,boost::core::invoke_swap 只提供基本异常保证。

在 C++11 及更高版本中,boost::core::invoke_swap 传播与底层 swap 函数中指定的相同的 noexcept 规范。

或者

  • T 必须是可复制赋值的(自 C++11 起:可移动赋值的)
  • T 必须是可复制构造的(自 C++11 起:可移动构造的)

或者

  • 具有签名 swap(T&, T&) 的函数可通过依赖于参数的查找获得

或者

  • std::swap 的模板特化存在于 T

或者

  • T 是一个可交换元素的内置数组

一些较旧的编译器不支持依赖于参数的查找。在这些编译器上,boost::core::invoke_swap 将调用 std::swap,忽略任何由于依赖于参数的查找而找到的特化 swap 函数。

  • **Niels Dekker** - 实现和记录了对内置数组的支持
  • **Joseph Gauterin** - 初始的想法、实现、测试和文档
  • **Steven Watanabe** - 提出了使 boost::swapstd::swap 特化程度更低的想法,从而允许该函数的名称为 'swap' 而不会引入歧义。 然而,后来该函数被重命名为 boost::core::invoke_swap,以避免潜在的无限递归。


[1] Scott Meyers, Effective C++ 第三版, Item 25: "考虑支持非抛出 swap"


PrevUpHomeNext