在实现自定义tuple(此处)时,我发现有一个swap()带有const参数的有线函数(cppreference):
template< class... Types >
constexpr void swap( const std::tuple<Types...>& lhs,
const std::tuple<Types...>& rhs ) noexcept(/* see below */);
Run Code Online (Sandbox Code Playgroud)
和一个 const 限定的swap()成员函数 ( cppreference ):
constexpr void swap( const tuple& other ) noexcept(/* see below */) const;
Run Code Online (Sandbox Code Playgroud)
const意味着该对象是只读的,但是要交换两个对象,它必须修改对象,这违反了性质const。
那么,const swap() 函数的目的是什么?
eer*_*ika 20
这是在最初在“C++23 Ranges 计划” P2214中描述的“zip”提案P2321中引入的。
P2321
交换 const 元组和 const 对。一旦引用元组被设置为可常量赋值,就可以为引用的常量元组调用默认的 std::swap 。然而,三步交换做了错误的事情:
Run Code Online (Sandbox Code Playgroud)int i = 1, j = 2; const auto t1 = std::tie(i), t2 = std::tie(j); // If std::swap(t1, t2); called the default triple-move std::swap then // this would do auto tmp = std::move(t1); t1 = std::move(t2); t2 = std::move(tmp); // i == 2, j == 2因此,本文建议为 const 元组和对添加交换重载,以正确执行逐元素交换。
P2214 解释了为什么实现 需要 const 可赋值性zip。它源于赋值运算符没有被 ref 限定。
您错过了有关何时可以使用该重载的脚注:
std::is_swappable_v<const Ti>仅当是true对于从 0 到 的所有 i时,此重载才参与重载决策sizeof...(Types)。
如果您有一个合理的类型const_swappable,swap(const const_swappable &, const const_swappable &)那么您没有理由不能进行 swap const std::tuple<const_swappable> &。