交换参考的临时元素
swap temporary tuples of references
我正在编写一个自定义迭代器,当reterended返回引用元组时。由于元组本身是短暂的,因此我认为我无法返回操作员*()的参考。我认为我的迭代器在语义上是有意义的,因为它具有参考语义,即使操作员*返回一个值。
。问题是,当我尝试调用std :: swap时(或者,当std :: sort所做时),如下所示,我会遇到错误,因为互换期望l值。这个问题有简单的解决方案吗?
#include <vector>
class test {
public:
test()
:v1(10), v2(10)
{}
class iterator {
public:
iterator(std::vector<int>& _v1,
std::vector<int>& _v2)
:v1(_v1), v2(_v2){}
std::tuple<int&, int&> operator*(){
return std::tuple<int&, int&>{v1[5], v2[5]};
}
std::vector<int>& v1;
std::vector<int>& v2;
};
std::vector<int> v1, v2;
};
int main(){
test t;
//error, Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/type_traits:3003:1: note: candidate function [with _Tp = std::__1::tuple<int &, int &>] not viable: expects an l-value for 1st argument
//deep within the bowels of std::sort ...
std::swap(*(test::iterator(t.v1, t.v2)),
*(test::iterator(t.v1, t.v2)));
}
在极少数情况下,可能需要获得临时引用。与std::move
相对的演员很容易实现:
template <typename T>
T & stay(T && t) { return t; }
用法:
std::swap(stay(foo()), stay(bar()));
正如您已经说过的,如果您无法更改呼叫网站,最好的选择可能是编写自己的参考包装器并使用ADL:
namespace detail
{
struct IntRefPair
{
int & a, & b;
IntRefPair(int & x, int & y) : a(x), b(y) {}
};
void swap(IntRefPair && lhs, IntRefPair && rhs)
{
std::swap(lhs.a, rhs.a);
std::swap(lhs.b, rhs.b);
}
}
// ...
IntRefPair operator*() { return IntRefPair(v1[5], v2[5]); } }
我想出的答案是写一个元组包装类:
template<typename ... Types>
struct tupleWrapper{
std::tuple<Types...> data;
tupleWrapper(std::tuple<Types...> _data) : data{_data}
{}
operator std::tuple<Types...> () {return data;}
std::tuple<Types...>& asTuple() {return data;}
};
template<typename ... Types>
void swap(tupleWrapper<Types ...> t1, tupleWrapper<Types ...> t2){
std::swap(t1.data, t2.data);
}
和一个可以使用ADL找到的GET功能,因为转换操作员在tad for std :: get。
时不会被调用template<int N, typename ...Ts>
auto get(tupleWrapper<Ts...> tw)->decltype(std::get<N>(tw.data)){
return std::get<N>(tw.data);
}
这不是理想的,但我认为它可以很好地工作。
您可以将std::tuple
作为数据成员放置并返回对此的引用:
class iterator
{
public:
iterator(std::vector<int>& _v1,
std::vector<int>& _v2)
: tup(_v1[5], _v2[5]) {}
tuple_of_references& operator*() const
{
return tup;
}
private:
typedef std::tuple<int&, int&> tuple_of_references; // just to cut down size
tuple_of_references tup;
};
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- C++错误消息*成员参考.**初学者*
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 维护对元素参考类型
- Cython:从参考获得时缺少两个前元素的 Numpy 数组
- 为什么此C 代码不起作用 - 试图删除集合中的元素时,请参考错误
- 调用clear()后,向量的元素仍然可以参考
- C 使用每个元素参考初始化数组
- 传递数组的一种病理方式:参考第一个元素
- 交换参考的临时元素