简体   繁体   English

专门用于右值的 std::swap

[英]specializing std::swap for rvalues

In the standard (20.2.2 [utility.swap]), std::swap is defined for lvalue references.在标准 (20.2.2 [utility.swap]) 中, std::swap 是为左值引用定义的。 I understand that this is the common case for when you want to swap two things.我知道这是您想要交换两件事的常见情况。 However, there are times when it's correct and desirable to swap rvalues (when temporary objects contain references, like here: swap temporary tuples of references ).但是,有时交换右值是正确且可取的(当临时对象包含引用时,例如: 交换引用的临时元组)。

Why isn't there an overload for rvalues?为什么右值没有重载? Does the risk of doing a meaningless swap on rvalues outweigh the potential benefits?对右值进行无意义交换的风险是否大于潜在收益?

Is there a legal way to support swapping rvalue std::tuple objects which contain references?是否有支持交换包含引用的右值 std::tuple 对象的合法方法? For a user defined type, I would specialize swap to accept its arguments by value, but it doesn't seem kosher to do the same for a library type like std::tuple.对于用户定义的类型,我会专门使用 swap 来按值接受它的参数,但对于像 std::tuple 这样的库类型来说,这样做似乎并不符合规范。

How about instead creating an lvalue_cast utility function that casts an rvalue to an lvalue: lvalue_cast创建一个将右值转换为左值的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';
}

Some STL algorithms would seem to require a swap for r-values if the iterator produced an r-value (for example a temporary).如果迭代器产生 r 值(例如临时值),一些 STL 算法似乎需要交换 r 值。

It is a valid discussion whether swap should work with r-values.交换是否应该与 r 值一起使用是一个有效的讨论。 I often see this problem because for "special" iterators, *it produces an r-value and sometimes you want to do the right things when "swapping".我经常看到这个问题,因为对于“特殊”迭代器, *it会产生一个 r 值,有时你想在“交换”时做正确的事情。

The workaround I found to not deal with this question was to specialize std::iter_swap for these special iterators in the first place.我发现不处理这个问题的解决方法是std::iter_swap为这些特殊迭代器专门化std::iter_swap I think that solve the problem for all STL algorithms.我认为这解决了所有 STL 算法的问题。

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

I think this is a fundamental customization point that all permuting STL algorithm miss and lack.我认为这是所有置换 STL 算法都遗漏和缺乏的基本定制点。

(Of course if we are at the point of hacking the STL we can as well do namespace std{template<class T, ...enable_if T&& is r-value ref just in case...> void swap(T&& t1, T&& t2){swap(t1, t2);} . But it is even more risky.) (当然,如果我们正在破解 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);} 。但风险更大。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM