How can I use C++11 variadic templates to define a vector-of-tuples backed by a tuple-of-vectors?

后端 未结 6 677
夕颜
夕颜 2020-12-13 11:20

Suppose I have a bunch of vectors:

vector v1;
vector v2;
vector v3;

all of the same length. Now, for ev

6条回答
  •  情话喂你
    2020-12-13 11:42

    From asker's clarification on how this would be used (code that takes a tuple), I'm going to propose this instead.

    //give the i'th element of each vector
    template
    inline tuple ith(size_t i, vector&... vs){
        return std::tie(vs[i]...);
    }
    

    There's a proposal to allow parameter packs to be saved as members of classes (N3728). Using that, here's some untested and untestable code.

    template
    class View{
    private:
        vector&... inner;
    
    public:
    
        typedef tuple reference;
    
        View(vector&... t): inner(t...) {}
    
        //return smallest size
        size_t size() const{
            //not sure if ... works with initializer lists
            return min({inner.size()...});
        }
    
        reference operator[](size_t i){
            return std::tie(inner[i]...);
        }
    };
    

    And iteration:

    public:
        iterator begin(){
            return iterator(inner.begin()...);
        }
        iterator end(){
            return iterator(inner.end()...);
        }
    
        //for .begin() and .end(), so that ranged-based for can be used
        class iterator{
            vector::iterator... ps;
            iterator(vector::iterator... its):ps(its){}
            friend View;
    
        public:
    
            //pre:
            iterator operator++(){
                //not sure if this is allowed.
                ++ps...;
                //use this if not:
                //  template void dummy(Types... args){} //global
                //  dummy(++ps...);
                return *this;
            }
            iterator& operator--();
            //post:
            iterator operator++(int);
            iterator operator--(int);
            //dereference:
            reference operator*()const{
                return std::tie(*ps...);
            }
            //random access:
            iterator operator+(size_t i) const;
            iterator operator-(size_t i) const;
            //need to be able to check end
            bool operator==(iterator other) const{
                return std::make_tuple(ps...) == std::make_tuple(other.ps...);
            }
            bool operator!=(iterator other) const{
                return std::make_tuple(ps...) != std::make_tuple(other.ps...);
            }
    
        };
    

提交回复
热议问题