c++ - 使用带有自定义类的 vector 复制构造函数不起作用?

标签 c++ c++11 linked-list constants copy-constructor

我正在尝试通过 LinkedList 实现 Hashtable 以解决冲突,但我在 Hashtable 内部实现复制构造函数时遇到问题(与 const 正确性混淆)。

这是我看到的错误:

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 复制构造器似乎可以工作,例如这编译:

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

但这不是:

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

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

std::vector<list*> table; 

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

最佳答案

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

关于c++ - 使用带有自定义类的 vector 复制构造函数不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24552963/

相关文章:

c++ - [C++]传节点索引好还是传节点本身好?哪个更快?

c++ - 使用 GCC 优化 C/C++ 循环中的嵌套 if 语句

C++函数装饰器

c++ - 如何申报 SFINAE 类(class)?

c++ - 为什么不首选 std::initializer_list 转换?

c - 使用数组创建单链表时的警告

c++ - 在取地址的上下文中,哪个是最专业的函数模板?

c++ - 何时在 C++ 中删除/取消引用

c++ - 搜索链表,不同的数据类型

java - 在 Java 中移动指针而不是某种列表或队列中的对象