图模板类

时间:2011-09-21 18:29:43

标签: c++ stl

我正在使用Graph Template Class。这是我到现在所写的。

#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 个答案:

答案 0 :(得分:1)

这需要两次隐式转换

  • 首先"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::stringVertex<std::string>。因此,它将编译。

答案 1 :(得分:1)

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:
};