This is my first time coding in C++ and I'm new to the generics in C++. I'm trying to make a little program that basically represents a graph and then traverse that graph using Breadth-First Search. I have made what I think is a generic graph and a generic BFS method. I have included all the code in case there is something I missed.
Here is the exact error:
no matching function for call to 'bfs(const char [4], Graph<std::__cxx11::basic_string<char> >&)
bfs("One", graph2);
Here is the code:
Graph.h :
#ifndef GRAPH_H
#define GRAPH_H
#include <map>
#include <iostream>
#include <list>
#include <set>
using namespace std;
template <class T>
class Graph{
private:
map<T, set<T>> adj_list;
public:
Graph();
void addVertex(T val, set<T> edges);
set<T> getNeighbours(T vertex);
};
#endif
Graph.cpp :
#include <iostream>
#include "Graph.h"
#include <string>
using namespace std;
template <class T>
Graph<T>:: Graph(){
;
}
// add vertex method
template <class T>
void Graph<T>:: addVertex(T val, set<T> edges){
//if the vertex is already created, the add the list of connections
//to that vertex, otherwise create a new vertex and create a new set
//of connections for the vertex
class map<T, set<T>> :: iterator it = adj_list.find(val);
if (it != adj_list.end()){
it->second.insert(edges.begin(), edges.end());
}
else{
adj_list.insert({val, edges});
}
// for all the connections, add the vertex to their corresponding
// connection set
for (T elem: edges){
class map<T, set<T>> :: iterator it1 = adj_list.find(elem);
if (it1 != adj_list.end()){
it1->second.insert(val);
}
else{
adj_list.insert({elem, {val}});
}
}
}
//get neighbours of given vertex
template <class T>
set<T> Graph<T>:: getNeighbours(T vertex){
return adj_list[vertex];
}
//override << operator. Display the adjacency list
template <class T>
inline ostream& operator<<(ostream& out, const Graph<T>& H){
out << "{\n";
for (class map<T, set<T>>::const_iterator it = H.adj_list.begin(), end = H.adj_list.end(); it != end;++it){
out << to_string(it->first) + " : ";
for (class set<T>::const_iterator lit = it->second.begin(), lend = it->second.end(); lit!= lend; ++lit){
if (distance(next(lit), lend) == 0){
out << to_string(*lit);
}
else{
out << to_string(*lit) + ", ";
}
}
out << "\n";
}
out << "}" << endl;
return out;
}
main.cpp :
#include <iostream>
#include "Graph.h"
#include "Graph.cpp"
#include <queue>
using namespace std;
template <class T>
void bfs(T vertex, Graph<T> graph){
// queue for bfs and set for checking if nodes have been visited
queue<T> myQueue;
set<T> visited;
//enqueue the vertex
myQueue.push(vertex);
//while there are still nodes to be visited
while (!myQueue.empty()){
//get the node to be searched next and add it to visited
T curr = myQueue.front();
myQueue.pop();
visited.insert(curr);
cout << "Visiting node:" << curr << endl;
//add all the nodes neighbours to the queue
for (T elem: graph.getNeighbours(curr)){
class set<T> :: iterator it = visited.find(elem);
//if the neighbours of the current node have been visitted then dont add to queue
if (it == visited.end()){
myQueue.push(elem);
}
}
}
}
int main(){
//initialize graph
Graph<int> graph1;
//create simple tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
set<int> connections1 = {2, 3};
set<int> connections2 = {4, 5};
set<int> connections3 = {6, 7};
graph1.addVertex(1, connections1);
graph1.addVertex(2, connections2);
graph1.addVertex(3, connections3);
// perfrom BFS
bfs(1, graph1);
Graph<string> graph2;
set<string> connectionsS1 = {"Two", "Three"};
set<string> connectionsS2 = {"Four", "Five"};
set<string> connectionsS3 = {"Six", "Seven"};
graph2.addVertex("One", connectionsS1);
graph2.addVertex("Two", connectionsS2);
graph2.addVertex("Three", connectionsS3);
bfs("One", graph2);
return 0;
}
The compiler is deducing the template type for bfs
from the arguments you pass it. As the first argument is of type const char[4]
it chooses that as the template type, this then fails as Graph<string>
is not convertible to Graph<const char[4]>
.
You can either pass a string as the first argument:
bfs(string("One"), graph2);
Or explicitly tell the compiler the template type:
bfs<string>("One", graph2);
I presume that bfs
should also be taking the graphs by reference rather than copying them?
void bfs(T vertex, const Graph<T>& graph)
You shouldn't include .cpp files, I guess you're doing so to avoid linker errors due to Why can templates only be implemented in the header file?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.