专业标准::交换右值
specializing std::swap for rvalues
在标准(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);}
.但这风险更大。
相关文章:
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- C++嵌套if语句,基本货币交换
- shell排序中的交换和比较
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 铸造标准::有没有回到原来的类型
- 是否有标准的文件保存和交换模式
- 为什么标准在移动分配运算符中使用交换?
- 为什么我的交换<字符串,字符串>比标准版本慢得多?
- 标准交换如何推断数组的长度
- 专业标准::交换右值
- 移动分配与标准复制和交换不兼容
- 专业标准::可选
- 标准::交换中不需要的析构函数调用
- 标准容器交换过载
- 交换unique_ptr(非标准Microsoft C++扩展)
- 为什么在c++ 11中交换标准库容器会有问题(涉及分配器)