swap temporary tuples of references

前端 未结 3 1521
执笔经年
执笔经年 2021-01-04 10:42

I\'m writing a custom iterator that, when dereferenced returns a tuple of references. Since the tuple itself is ephemeral, I don\'t think I can return a reference from oper

相关标签:
3条回答
  • 2021-01-04 10:49

    The answer I came up with was to write a tuple wrapper class:

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

    And a get function that can be found with ADL, since the conversion operator doesn't get called when doing 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);
    }
    

    It's not ideal, but I think it will work well enough.

    0 讨论(0)
  • 2021-01-04 10:59

    You can place the std::tuple as a data member and return a reference to that:

    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;
    };
    
    0 讨论(0)
  • 2021-01-04 11:07

    On rare occasions it may be desirable to get an lvalue reference to temporary. This easily achieved with a cast opposite to std::move:

    template <typename T>
    T & stay(T && t) { return t; }
    

    Usage:

    std::swap(stay(foo()), stay(bar()));
    

    As you already said, if you can't change the call site, your best option may be to write your own reference wrapper and use ADL for that:

    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]); } }
    
    0 讨论(0)
提交回复
热议问题