c++ - 交换引用的临时元组

标签 c++ tuples swap rvalue

我正在编写一个自定义迭代器,它在取消引用时返回一个引用元组。由于元组本身是短暂的,我认为我无法从 operator*() 返回引用。我认为我的迭代器在语义上是有意义的,因为它具有引用语义,即使 operator* 返回一个值也是如此。

问题是,当我尝试调用 std::swap 时(或者更确切地说,当 std::sort 调用时),如下所示,我收到错误,因为交换需要左值。有解决此问题的简单方法吗?

#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)));
}

最佳答案

关于 rare occasions获得临时的左值引用可能是可取的。这很容易通过与 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]); } }

关于c++ - 交换引用的临时元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21588477/

相关文章:

linux - 我如何知道哪个进程正在使用交换?

c++ - 无法读取包含→的wstrings并打印输入的unicode字符

c++ - 派生类构造函数内部如何调用基类构造函数

python - 如何将 numpy 元组数组乘以标量数组

javascript - 在 JavaScript 中打乱数组属性

c++ - C++:交换两个不同 vector 的两个元素

c++ - 将文件转换为列表 C++ 的最快方法

c++ - GTK+ 对多个小部件使用一个处理程序

python - 从列表中的字典元组创建字典的字典

python - 如何在类型提示中定义元组或列表的大小