jeudi 20 août 2020

Error while creating variadic class in C++

I am trying to create a class that when provided with a list of pairs of iterator begin and ends generates a sequence of vectors that give the cartesian product of the elements in the input vectors.

The code works when 2 pairs of iterators are given to the initializer of the class. However, when another pair is added, it fails to compile.

iterators.h

template<typename InputIterator,typename ...InputIterators>
class Product{
    typedef  typename std::iterator_traits<InputIterator>::value_type base_value;
    InputIterator base,end,curr;
    Product* next = nullptr;
    void reset(){
        curr = base;
    }
public:
    explicit Product(InputIterator begin,InputIterator end,InputIterators... args) :base(begin),end(end){
        curr = begin;
        next = new Product(args...);
    }
    explicit Product(InputIterator begin,InputIterator end):base(begin),end(end){
        curr=begin;
    }
    bool has_next(){
        if (!next){
            return curr+1!=end;
        }
        return next->has_next() || (curr+1)!=end;
    }
    Product& operator++(){
        if (!next){
            curr++;
            return *this;
        }
        if(!next->has_next()){
            curr++;
            next->reset();
            return *this;
        }
        ++(*next);
        return *this;
    }

    std::vector<base_value> operator*(){
        if(!next){
            return std::vector<base_value>({*curr});
        }
        std::vector<base_value> ans = *(*next);
        ans.insert(ans.begin(),*curr);
        return ans;
    }



};

main.cpp

#include<vector>
#include"itertools.h"
int main(){
    std::vector<int> a = {0,1,2,3},b = {4,5,6};
    auto q = Product(a.begin(),a.end(),b.begin(),b.end());

    auto w =  *q;
    for(auto i:w){
        std::cout<<i<<' ';
    }
    std::cout<<std::endl;
while(q.has_next()) {
    ++q;
     w = *q;
    for (auto i:w) {
        std::cout << i << ' ';
    }
    std::cout << std::endl;
}
}
    return 0;
}

error

In file included from main.cpp:4:
itertools.h:91:20: error: no matching constructor for initialization of 'Product<std::__1::__wrap_iter<int *>, std::__1::__wrap_iter<int *>, std::__1::__wrap_iter<int *>, std::__1::__wrap_iter<int *>, std::__1::__wrap_iter<int *> >'
        next = new Product(args...);
                   ^       ~~~~
main.cpp:11:14: note: in instantiation of member function 'Product<std::__1::__wrap_iter<int *>, std::__1::__wrap_iter<int *>, std::__1::__wrap_iter<int *>, std::__1::__wrap_iter<int *>, std::__1::__wrap_iter<int *> >::Product' requested here
    auto q = Product(a.begin(),a.end(),b.begin(),b.end(),b.begin(),b.end());
             ^
itertools.h:93:14: note: candidate constructor not viable: requires 2 arguments, but 4 were provided
    explicit Product(InputIterator begin,InputIterator end):base(begin),end(end){
             ^
itertools.h:89:14: note: candidate constructor not viable: requires 6 arguments, but 4 were provided
    explicit Product(InputIterator begin,InputIterator end,InputIterators... args) :base(begin),end(end){
             ^
itertools.h:81:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 4 were provided
class Product{
      ^
itertools.h:81:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 4 were provided
1 error generated.

Aucun commentaire:

Enregistrer un commentaire