无法从const T转换为const T&

时间:2019-04-01 14:12:42

标签: c++

我有一个方法void Graph<T>::remove_vertex(const T& t);
会调用graph_.get(t);

graph_的类型为List<Vertex*>
其中有一个我无法调用的T& get(const T& t);方法。

List是我自己的std::list

实现

我收到的错误消息是:

Error   C2664   'T &List<T>::get(const T &) const': cannot convert argument 1 from 'const T' to 'const T &' O2  c:\users\sorn\source\repos\o2\o2\graph.h    80  


List.h

#pragma once

template<typename T>
class List
{
public:
    struct Iterator;

    List();
    ~List();

    void push_back(const T&);
    void push_front(const T&);
    void pop_back();
    void pop_front();
    void clear();
    Iterator erase(Iterator it);

    T& front() const;
    T& back() const;
    T& get(const T&) const;
    int size() const;
    bool empty() const;
    Iterator begin();
    Iterator end();
protected:
    struct Link;
    struct Node;

    void unlink(Link*);

    Link* sentinel_;
    int size_;
};

template<typename T>
struct List<T>::Link
{
    Link() : next(this), prev(this) { /**/ }
    Link* next;
    Link* prev;
};

template<typename T>
struct List<T>::Iterator
{
    Iterator() = default;
    Iterator(Node* n) : node(n) {}
    T& operator*() { return node->value; }
    bool operator==(const Iterator& rhs) { return (node->value == rhs.node->value); }
    bool operator!=(const Iterator& rhs) { return (node->value != rhs.node->value); }
    Iterator& operator++()
    { 
        node = static_cast<Node*>(node->next);
        return *this;
    }
private:
    Node* node;
    friend List;
};

template<typename T>
struct List<T>::Node : public Link
{
    Node(const T& v) : value(v) { /**/ }
    T value;
};

template<typename T>
List<T>::List() : size_(0)
{
    sentinel_ = new Link;
}

template<typename T>
List<T>::~List()
{
    clear();
    delete sentinel_;
}

template<typename T>
void List<T>::push_back(const T& t)
{
    Node* n = new Node(t);
    n->next = sentinel_;
    n->prev = sentinel_->prev;
    sentinel_->prev->next = n;
    sentinel_->prev = n;
    ++size_;
}

template<typename T>
void List<T>::push_front(const T& t)
{
    Node* n = new Node(t);
    n->next = sentinel_->next;
    n->prev = sentinel_;
    sentinel_->next->prev = n;
    sentinel_->next = n;
    ++size_;
}

template<typename T>
void List<T>::pop_back()
{
    Link* tmp = sentinel_->prev;
    unlink(tmp);
    delete tmp;
    --size_;
}

template<typename T>
void List<T>::pop_front()
{
    Link* tmp = sentinel_->next;
    unlink(tmp);
    delete tmp;
    --size_;
}

template<typename T>
void List<T>::clear()
{
    while (!empty())
    {
        pop_back();
    }
}

template<typename T>
T& List<T>::get(const T& t) const
{
    for (Iterator it = begin(); it != end(); ++it)
    {
        if (*it == t) return *it;
    }
}

template<typename T>
typename List<T>::Iterator List<T>::erase(Iterator it)
{
    Node* prev = it.node;
    unlink(it.node);
    delete it.node;
    return Iterator(prev);
}

template<typename T>
T& List<T>::front() const
{
    Node* n = static_cast<Node*>(sentinel_->next);
    return n->value;
}

template<typename T>
T& List<T>::back() const
{
    Node* n = static_cast<Node*>(sentinel_->prev);
    return n->value;
}

template<typename T>
int List<T>::size() const
{
    return size_;
}

template<typename T>
bool List<T>::empty() const
{
    return size_ == 0;
}

template<typename T>
typename List<T>::Iterator List<T>::begin()
{
    return Iterator(static_cast<Node*>(sentinel_->next));
}

template<typename T>
typename List<T>::Iterator List<T>::end()
{
    return Iterator(static_cast<Node*>(sentinel_));
}

template<typename T>
void List<T>::unlink(Link* l)
{
    l->next->prev = l->prev;
    l->prev->next = l->next;
    l->next = l;
    l->prev = l;
}


Graph.h

#pragma once

#include "List.h"

template<typename T>
class Graph
{
public:
    ~Graph();

    void print();

    void add_vertex(const T&);
    void remove_vertex(const T&);

    //virtual void add_edge(const T&, const T&, int weight) = 0;
    //virtual void remove_edge(const T&, const T&) = 0;
protected:
    struct Vertex;
    struct Edge;
private:
    List<Vertex*> graph_;
};

template<typename T>
struct Graph<T>::Vertex
{
    Vertex(T t) : value(t) {}
    bool operator==(const Vertex& rhs) { return value == rhs.value; }
    T value;
    List<Edge*> in;
    List<Edge*> out;
};

template<typename T>
struct Graph<T>::Edge
{
    Vertex* destination;
    int weight;
};

template<typename T>
Graph<T>::~Graph()
{
    // TODO:
}

template<typename T>
void Graph<T>::print()
{
    for (Vertex* v : graph_)
    {
        std::cout << v->value << " -> ";
        std::cout << "[in = {";
        for (Edge* e : v->in)
        {
            std::cout << ' ' << e->destination;
        }
        std::cout << " }], ";
        std::cout << "[out = {";
        for (Edge* e : v->out)
        {
            std::cout << ' ' << e->destination;
        }
        std::cout << " }]";
        std::cout << std::endl;
    }
}

template<typename T>
void Graph<T>::add_vertex(const T& t)
{
    Vertex* v = new Vertex(t);
    graph_.push_back(v);
}

template<typename T>
void Graph<T>::remove_vertex(const T& t)
{
    Vertex* v = graph_.get(t);
    while (!v->out.empty())
    {
        Edge* e = v->out.back();
        Vertex* dest = e->destination;
        auto it = dest->in.begin();
        while (it != dest->in.end())
        {
            Edge* e = *it;
            Vertex* w = dest;
            if (v == w)
                break;
            ++it;
        }
        dest->in.erase(it);
        v->out.pop_back();
    }
    while (!v->in.empty())
    {
        Edge* e = v->in.back();
        Vertex* dest = e->destination;

        auto it = dest->out.begin();
        while (it != dest->out.end())
        {
            Edge* e = *it;
            Vertex* w = e->destination;
            if (v == w)
                break;
            ++it;
        }
        dest->out.erase(it);
        v->in.pop_back();
    }
}

2 个答案:

答案 0 :(得分:2)

您似乎以某种方式混淆了Graph模板及其包含的List<Vertex*>类的模板参数。

致电时

Vertex* v = graph_.get(t);

t的类型可能不是 Vertex*。但是您致电List<Vertex*>::get(Vertex*&)t的类型与编译器告诉您的Vertex*不匹配(但是您也不显示完整的错误消息,应该有更多的信息,例如有关模板类型的信息)。

确切的解决方法很难说,因为您的问题中没有足够的信息。

答案 1 :(得分:0)

它比较了错误的T在一起。
我将列表模板类型名称更改为U,现在它说不能将const Tconst U&进行比较。这就是问题所在。

enter image description here