Нужна помощь, я не понимаю, почему следующий код не компилируется - PullRequest
2 голосов
/ 29 сентября 2010

Заголовочный файл "graph.h"

#ifndef _GRAPH_H_
#define _GRAPH_H_

#include <map>
#include <vector>

using namespace std;

template <class T>
class VERTEX
{
public:
    VERTEX(T inVertex): m_vertex(inVertex), m_visited(false){}
    ~VERTEX(){}
private:
    T m_vertex;
    bool m_visited;
};

template <class T>
class GRAPH
{
public:
    GRAPH() {}
    ~GRAPH(){}
    typedef VERTEX<T> GRAPHVERTEX;
    typedef vector<GRAPHVERTEX> ADJLIST;
    typedef map<GRAPHVERTEX, ADJLIST> GRAPHMAP;

    void insert(GRAPHVERTEX inSRC, GRAPHVERTEX inDST)
    {
        GRAPHMAP::iterator itr = m_graph.find(inSRC);
    }

private:
    GRAPHMAP m_graph;
};

#endif

И тестовый файл

#include "graph.h"

int main( int argc, char**argv)
{
    GRAPH<int> *G = new GRAPH<int>();
    G->insert(VERTEX<int>(0), VERTEX<int>(2));
    return 0;
}

Ответы [ 4 ]

3 голосов
/ 29 сентября 2010

Есть две проблемы.

Сначала необходимо указать зависимый тип в insert:

void insert(GRAPHVERTEX inSRC, GRAPHVERTEX inDST)
{
    typename GRAPHMAP::iterator itr = m_graph.find(inSRC);
}

Во-вторых, вам нужен оператор <для вашего класса вершин. В публичном разделе VERTEX добавьте: </p>

bool operator<(const VERTEX<T>& right) const { return m_vertex < right.m_vertex; }

Обратите внимание, что в C ++ имена всех CAPS обычно зарезервированы для констант. Vertex было бы гораздо более нормальным названием для вашего класса. Также обратите внимание, что наличие using namespace в заголовке может иметь много нежелательных и непредсказуемых результатов в зависимости от порядка включения и его следует полностью избегать.

РЕДАКТИРОВАТЬ: По крайней мере, когда я скомпилировал это с g ++, первая ошибка, которую я получил, касалась GRAPHMAP :: iterator. Когда компилятор видит идентификатор, который можно рассматривать как переменную или тип, он выбирает интерпретировать его как переменную по умолчанию, но затем обнаруживает, что на самом деле это был тип. Вы говорите компилятору, что это действительно тип, используя ключевое слово typename.

Второе, на что следует обратить внимание, это то, что map является упорядоченным контейнером, и поэтому вам необходимо либо передать функцию сравнения, либо предоставить <оператор для ключа <code>map. Поскольку VERTEX является ключом карты, я настроил operator<, чтобы объекты можно было сортировать и поддерживать порядок. Возможно, вам придется настроить оператор сравнения по мере развития вашего VERTEX класса.

1 голос
/ 29 сентября 2010

Вы не можете создать карту с GRAPHVERTEX в качестве ключа, потому что вам нужно иметь возможность сравнить ключ с оператором <.Таким образом, вы должны определить этот оператор. </p>

0 голосов
/ 29 сентября 2010

Чтобы использовать класс в качестве ключа на карте, вы должны либо определить operator< для этого типа, либо вам нужно указать компаратор при создании карты. Предполагая, что объекты этого типа имеют «естественный» порядок, вы обычно хотите использовать его для реализации operator<. Обычно вы используете отдельный объект компаратора, когда вам нужно упорядочить объекты данного типа в несколько разных порядков, и ни один из них не является более «естественным» или доминирующим, чем другие (например, при работе с сотрудниками у них примерно одинаково часто по номеру социального страхования, имени и стажу).

0 голосов
/ 29 сентября 2010

Ваш класс VERTEX используется в качестве ключа на карте;требуется, чтобы был определен оператор «поменьше».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...