const swap() 函数的用途是什么?

方圆圆*_*方圆圆 32 c++ stdtuple

在实现自定义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 。然而,三步交换做了错误的事情:

    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
    
    Run Code Online (Sandbox Code Playgroud)

    因此,本文建议为 const 元组和对添加交换重载,以正确执行逐元素交换。

P2214 解释了为什么实现 需要 const 可赋值性zip。它源于赋值运算符没有被 ref 限定。


Cal*_*eth 5

您错过了有关何时可以使用该重载的脚注:

std::is_swappable_v<const Ti>仅当是true对于从 0 到 的所有 i时,此重载才参与重载决策sizeof...(Types)

如果您有一个合理的类型const_swappableswap(const const_swappable &, const const_swappable &)那么您没有理由不能进行 swap const std::tuple<const_swappable> &