图模板类

发布于 2024-12-05 13:02:59 字数 1404 浏览 1 评论 0原文

我正在研究图形模板类。这是我到目前为止所写的。

#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 给我编译错误。 错误 C2664: 'Graph<_Ty>::AddEdge' : 无法将参数 1 从 'const char [2]' 转换为 'Graph<_Ty>::Vertex<_Ty>'

为什么这是错误,如果 std::string test = "ABC"; 有效。

I am working on Graph Template Class. Here is what I written till now.

#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

Here is how I am using this class.

#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 is giving me compilation error.
error C2664: 'Graph<_Ty>::AddEdge' : cannot convert parameter 1 from 'const char [2]' to 'Graph<_Ty>::Vertex<_Ty>'

Why this is error , if std::string test = "ABC"; works.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅唱ヾ落雨殇 2024-12-12 13:02:59

std::string test = "ABC"; 进行隐式转换,但在调用函数时不会发生。尝试 myGraph3.AddEdge(std::string("A"),std::string("B"));。

通过定义另一个函数来重载函数调用,如

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

help 中所示。

您的代码的另一个问题(至少对于 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:
};

std::string test = "ABC"; does implicit casting, but it is not happening while calling the function. Try myGraph3.AddEdge(std::string("A"),std::string("B"));.

Function call overloading by defining another function as in

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

helps.

The other issue with your code (at least for gcc) is that you are using the same parameter _Ty in two nested template declarations. The complete, correct code, that works for me is:

#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:
};
夏见 2024-12-12 13:02:59

这需要两次隐式转换,

  • 首先"A"需要转换为std::string
  • 然后std::string需要转换为 Vertex (嵌套类型)。

这是不允许的链式隐式转换。

但是,当您编写 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。因此,它将编译。

That requires two implicit conversions

  • First "A" needs to convert into std::string
  • Then std::string needs to convert into Vertex<std::string> (the nested type).

That is chained-implicit-conversion which is not allowed.

But when you write std::string test = "ABC", then only one conversion happens: char[4] to std::string. That is it.

So the solution is, do one conversion yourself by explicitly passing std::string, and let the compiler do the other conversion:

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

Now only one conversion is needed : std::string to Vertex<std::string>. Therefore, it will compile.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文