Граф Шаблон класса - PullRequest
       7

Граф Шаблон класса

0 голосов
/ 21 сентября 2011

Я работаю над классом шаблонов графиков. Вот что я написал до сих пор.

#ifndef __GRAPH_H__
#define __GRAPH_H__

#include <map>
#include <list>

template <typename _Ty>
class Graph {
private:
    template <typename _Ty>
    class Vertex {
    public:
        Vertex(_Ty in) : m_Label(in) {
        }
        ~Vertex() {
        }
    private:
        _Ty m_Label;
    protected:
    };

public:
    typedef Vertex<_Ty>                       VertexType;
    typedef std::list<VertexType>             AdjListType;
    typedef std::map<VertexType,AdjListType>  GraphType;

public:
    Graph(bool bType = false) : m_Type(bType) {
    }
    ~Graph() {
    }
    void AddEdge(VertexType vLevt, VertexType vRight) {
    }
private:
    // true if bidirectional
    // false if unidirectional.
    bool m_Type; 
    GraphType m_Graph;
protected:
};

#endif

Вот как я использую этот класс.

#include "Graph.h"
#include <string>

int main(int argc, char **argv) {
    Graph<int> myGraph;
    myGraph.AddEdge(1,2);

    Graph<char *> myGraph2;
    myGraph2.AddEdge("A","B");

    Graph<std::string> myGraph3;
    myGraph3.AddEdge("A","B");

}

myGraph3 дает мне ошибку компиляции. error C2664: 'Graph<_Ty>::AddEdge' : cannot convert parameter 1 from 'const char [2]' to 'Graph<_Ty>::Vertex<_Ty>'

Почему это ошибка, если std::string test = "ABC"; работает.

Ответы [ 2 ]

1 голос
/ 21 сентября 2011

std::string test = "ABC"; выполняет неявное приведение, но это не происходит при вызове функции. Попробуйте myGraph3.AddEdge(std::string("A"),std::string("B"));.

Перегрузка вызова функции путем определения другой функции, как в

void AddEdge(_Ty vLevt, _Ty vRight) {
        this->AddEdge((VertexType) vLevt, (VertexType) vRight);
    }

помогает.

Другая проблема с вашим кодом (по крайней мере, для gcc) заключается в том, что вы используете один и тот же параметр _Ty в двух вложенных объявлениях шаблонов. Полный, правильный код, который работает для меня:

#include <map>
#include <list>

template <typename _Ty>
class Graph {
private:
    template <typename _Tyv>
    class Vertex {
    public:
        Vertex(_Tyv in) : m_Label(in) {
        }
        ~Vertex() {
        }
    private:
        _Tyv m_Label;
    protected:
    };

public:
    typedef Vertex<_Ty>                       VertexType;
    typedef std::list<VertexType>             AdjListType;
    typedef std::map<VertexType,AdjListType>  GraphType;

public:
    Graph(bool bType = false) : m_Type(bType) {
    }
    ~Graph() {
    }
    void AddEdge(VertexType vLevt, VertexType vRight) {
    }
    void AddEdge(_Ty vLevt, _Ty vRight) {
        this->AddEdge((VertexType) vLevt, (VertexType) vRight);
    }
private:
    // true if bidirectional
    // false if unidirectional.
    bool m_Type;
    GraphType m_Graph;
protected:
};
1 голос
/ 21 сентября 2011

Это требует двух неявных преобразований

  • Сначала "A" необходимо преобразовать в std::string
  • Затем std::string необходимо преобразовать в Vertex<std::string> (вложенный тип).

Это цепное-неявное преобразование, которое не допускается.

Но когда вы пишете std::string test = "ABC", происходит только одно преобразование: char[4] в std::string. Вот и все.

Таким образом, решение состоит в том, чтобы выполнить одно преобразование самостоятельно, явно передав std::string, и пусть компилятор сделает другое преобразование:

 Graph<std::string> myGraph3;
 myGraph3.AddEdge(std::string("A"),std::string("B"));

Теперь требуется только одно преобразование: std::string в Vertex<std::string>. Поэтому он скомпилируется.

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