mardi 30 mai 2017

Setting Preference over Constructor in Template Member Function in Template class

I'm trying to create my own implementation of a doubly-linked list for learning purpose. I wanted to use a template class to do this. I have a few constructors that have the definition like this:

template <typename TYPE>
class DList {
public:
    DList(const size_t size, const TYPE& val = TYPE());

    template <typename ITER>
    DList(ITER&& begin, ITER&& end);
};

(I have more code that I have omitted).

The first constructor copies the value provided size times (so DList<int>(5, 2) would copy the number 2, 5 times)

The second constructor copies a range (between 2 Iterators) in to the list. (so DList<int>(other.begin(), other.end()) would copy one data structure in to the DList)

The question is that how do I set the preference of the two constructors? For example if I'm instantizing my class with this line:

DList<int> listTest2(6, 2);

The compiler gets confused and chooses the iterator based constructor over the size constructor and throws errors. I want to keep the template iterator constructor because I have other classes like that one (that implements other data structures) and the iterators is a class inside the class. (so DList has a class inside it called iterator, see below for more info on what I mean).

Is there anyway to set a preference over which constructor gets called. I want it to work like how I can call std::vector<int>(other.begin, other.end) and std::vector<int>(2, 3) and both work.

I have attached the header file for my template class below:

template <typename TYPE>
class DList {
public:
    struct Node {
        Node* prev;
        TYPE data;
        Node* next;
    };

    class iterator {
    public:
        iterator();
        iterator(const Node* node);
        iterator(const iterator& it);

        iterator& operator++(); // preincrement
        iterator& operator--();

        iterator operator++(int); // postincrement
        iterator operator--(int);

        iterator& operator=(const iterator& it);

        iterator& operator-(int scale);
        iterator& operator+(int scale);

        bool operator==(const iterator& it);

        TYPE& operator*();
        TYPE& operator->();

        Node* getNode();

    private:
        Node* data;

    };

    DList();
    DList(const DList& other);

    DList(const size_t size, const TYPE& val = TYPE());

    template <typename ITER>
    DList(ITER&& begin, ITER&& end);

    iterator begin() const;
    iterator end() const;

    void clear();

    void push_back(const TYPE& val);
    void push_front(const TYPE& val);

    void pop_back();
    void pop_front();

    void insert(size_t idx, const TYPE& val);
    void insert(const DList<TYPE>::iterator it, const TYPE& val);
    void remove(const TYPE& val);

    size_t size() const;

    const TYPE& operator[](size_t idx) const;
    TYPE& operator[](size_t idx);

private:    
    Node* mHead; /// @todo convert to iterators?
    Node* mTail;
    size_t mSize;

};

Aucun commentaire:

Enregistrer un commentaire