专业标准::交换右值

specializing std::swap for rvalues

本文关键字:交换 专业标准      更新时间:2023-10-16

在标准(20.2.2 [utility.swap])中,std::swap是为左值引用定义的。 我知道这是您想要交换两件事的常见情况。 但是,有时交换右值是正确的和可取的(当临时对象包含引用时,如下所示:交换引用的临时元组)。

为什么右值没有过载? 对净值进行无意义的掉期风险是否超过潜在收益?

是否有合法的方法支持交换包含引用的右值 std::tuple 对象? 对于用户定义的类型,我会专门使用 swap 来按值接受其参数,但对于像 std::tuple 这样的库类型做同样的事情似乎并不洁食。

不如创建一个将右值转换为左值的lvalue_cast效用函数:

#include <tuple>
#include <iostream>
template <class T>
T&
lvalue_cast(T&& t)
{
    return t;
}
int
main()
{
    int i = 1;
    int j = 2;
    swap(lvalue_cast(std::tie(i)), lvalue_cast(std::tie(j)));
    std::cout << i << 'n';
    std::cout << j << 'n';
}

如果迭代器生成 r 值(例如临时值),某些 STL 算法似乎需要交换 r 值。

交换是否应该与 r 值一起使用是一个有效的讨论。我经常看到这个问题,因为对于"特殊"迭代器,*it会产生一个 r 值,有时你想在"交换"时做正确的事情。

我发现不处理这个问题的解决方法是首先为这些特殊迭代器专门std::iter_swap。我认为这解决了所有 STL 算法的问题。

namespace std{
void iter_swap(special_iterator it1, special_iterator it2){
   ... special swap of pointed values
}
}

我认为这是所有排列 STL 算法都错过和缺乏的基本定制点。

(当然,如果我们正处于破解STL的地步,我们也可以这样做 namespace std{template<class T, ...enable_if T&& is r-value ref just in case...> void swap(T&& t1, T&& t2){swap(t1, t2);} .但这风险更大。