使用向量复制构造函数与自定义类不起作用?

时间:2014-07-03 11:51:29

标签: c++ c++11 linked-list const copy-constructor

我试图通过LinkedList实现Hashtable冲突,我在Hashtable中实现拷贝构造函数时遇到问题(与const-correctness东西混淆)。

这是我看到的错误:

void LinkedList<KVP<T>>::add(const KVP<T> &)' : cannot convert argument 1 from 'const int' to 'const KVP<T> &

这是我的代码:

哈希表

#include <stdlib.h>
#include <string>
#include <vector>
#include "LinkedList.h"
#pragma once

template <typename T>
struct KVP
{
    KVP() {}
    KVP(const T &data, const std::string &key) : data(data), key(key) {}
    const std::string key;
    T data;
};

template <typename T>
class Hashtable
{
    typedef KVP<T> kvp;
    typedef LinkedList<kvp> list;

    std::vector<list> table;
    std::size_t size;

public:

    Hashtable(int size) : size(size), table(size) {}
    Hashtable(const Hashtable& other) : size(other.size) 
    {
        table = other.table; //this causes problems
    }
    Hashtable& operator=(Hashtable other)
    {
        swap(*this, other);
        return *this;
    }
    ...  
};

关联列表:

#include <stdlib.h>
#include <memory>

#pragma once

template <typename T>
class LinkedList;

template <typename TNode>
class LinkedListIterator
{
    friend class LinkedList<typename TNode::value_type>;
    TNode* p;
public:
    LinkedListIterator(TNode* p) : p(p) {}
    LinkedListIterator(const LinkedListIterator& other) : p(other.p) {}
    LinkedListIterator& operator=(LinkedListIterator other) { std::swap(p, other.p); return *this; }
    void operator++() { p = p->next; }
    void operator++(int) { p = p->next; }
    bool operator==(const LinkedListIterator& other) { return p == other.p; }
    bool operator!=(const LinkedListIterator& other) { return !(p == other.p); }
    const int& operator*() const { return p->data; }
    LinkedListIterator<TNode> operator+(int i)
    {
        LinkedListIterator<TNode> iter = *this;
        while (i-- > 0 && iter.p)
        {
            ++iter;
        }
        return iter;
    }
};

template <typename T>
class Node
{
    friend class LinkedList<T>;
    friend class LinkedListIterator<Node<T>>;
    friend class LinkedListIterator<const Node<T>>;

    Node() : next(nullptr) {}
    Node(const T &data) : data(data), next(nullptr) {}
    Node<T> *next;
    T data;
public:
    typedef T value_type;
};

template <typename T>
class LinkedList
{
    typedef Node<T> node;

    std::size_t size;
    std::unique_ptr<node> head;
    std::unique_ptr<node> tail;

    void init()
    {
        size = 0;
        head.reset(new node);
        tail.reset(new node);
        head->next = tail.get();
    }

public:
    typedef LinkedListIterator<node> iterator;
    typedef LinkedListIterator<const node> const_iterator;

    LinkedList() { init(); }

    LinkedList(const LinkedList& other)
    {
        init();
        const_iterator i = other.begin();
        while (i != other.end())
        {
            add(*i);
            i++;
        }

        head.reset(other.head.get());
        tail.reset(other.tail.get());
    }

    LinkedList(LinkedList&& other)
    {
        size = other.size;
        head = other.head;
        tail = other.tail;
        other.size = 0;
    }

    LinkedList& operator=(LinkedList other)
    {
        swap(*this, other);
        return *this;
    }

    LinkedList& operator=(LinkedList&& other)
    {
        assert(this != &other);     
        while (head->next != tail)
            remove(begin());
        head = other.head;
        tail = other.tail;
        size = other.size;
        other.size = 0;
        return *this;
    }

    virtual ~LinkedList()
    {
        while (head->next != tail.get())
            remove(begin());
    }

    friend void swap(LinkedList& first, LinkedList& second)
    {
        std::swap(first.size, second.size);
        std::swap(first.head, second.head);
        std::swap(first.tail, second.tail);
    }

    void add(const T &value)
    {
        node *first = new node(value);
        first->next = head->next;
        head->next = first;
        size++;
    }

    void remove(iterator& removeIter)
    {
        node *last = head.get();
        iterator i = begin();

        while (i != removeIter)
        {
            last = i.p;
            ++i;
        }

        if (i != end())
        {
            last->next = i.p->next;
            size--;
            delete i.p;
        }
    }

    const int getSize() 
    { 
        return size;
    }

    iterator begin() 
    {
        return iterator(head->next);
    }

    const_iterator begin() const
    {
        return const_iterator(head->next);
    }

    iterator end()
    {
        return iterator(tail.get());
    }

    const_iterator end() const
    {
        return const_iterator(tail.get());
    }
};

在它自己的LinkedList副本ctor似乎工作,例如这编译:

LinkedList<int> list;
LinkedList<int> list2;
list2 = list;

但这不是:

Hashtable<int> table1(50);
Hashtable<int> table2 = table1;

编辑:如果我用指针定义表:

std::vector<list*> table; 

它有效,但我不认为这是最好的方式。

1 个答案:

答案 0 :(得分:1)

您的LinkedListIterator<const Node<T>>::operator*会返回const int&,而不是LinkedList<T>的值类型。您的LinkedList<int>测试已通过,因为模板参数恰好与硬编码的返回类型operator*匹配。