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 > 1T 的底层 swap 函数提供强异常保证,boost::core::invoke_swap 仅提供基本异常保证。

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

或者

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

或者

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

或者

  • 存在 std::swapT 的模板特化

或者

  • 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++ 第三版》,第 25 项:“考虑支持无异常抛出的 swap”


PrevUpHomeNext