Reputation: 13257
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.
Upvotes: 0
Views: 4369
Reputation: 17321
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:
};
Upvotes: 1
Reputation: 361352
That requires two implicit conversions
"A"
needs to convert into std::string
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.
Upvotes: 1