My code runs in a Windows environment with Visual Studio but does not seem to compile in Linux. I have been troubleshooting for a very long time but cannot for the life of me figure out what is wrong.
The errors in my programs read "error: invalid initialization of non-const reference of type 'Edge&' from an rvalue of type 'Edge'
What I don't understand is why Linux seems to have an issue with it, as it is not syntactically incorrect since it does compile in a Windows environment. What is it I need to change for this thing to run on Linux?
I have included what I think is the relevant code for one of the programs, the first one in the link, since the other has the same errors.
EDIT: I am using g++ to compile my code in Linux. If you need any other information, please let me know since I don't know what information may be relevant based on the error message and my inexperience with Linux.
command line errors: https://i.stack.imgur.com/9iY2I.jpg
Graph.h:
#ifndef _H_GRAPH_H
#define _H_GRAPH_H
#include <fstream>
#include <string>
#include <iostream>
#include "Hashtable.h"
#include <sstream>
#include "Vertex.h"
#include "LinkedStack.h"
#include "LinkedQueue.h"
#include "IllegalArgumentException.h"
using namespace std;
#define INFINITY 1000000
template <class T>
class Graph{
public:
//constructor
Graph(){
numVertices = 0;
}
//destructor
~Graph(){}
///////////////////////////Accessors//////////////////
//Returns true if the graph is empty, false otherwise
bool empty() const{
return numVertices == 0;
}
//Returns the indegree of the vertex v. Throw
//an illegal argument exception if the argument does not correspond to an existing vertex.
int indegree(string v){
Vertex<T>* vertex = hashtable.get(v);
if (vertex == NULL)
{
throw IllegalArgumentException();
}
LinkedList<Vertex<T>*> linkedlist;
hashtable.getVertices(linkedlist);
int count = 0;
//iterate the list
LinkedListNode<Vertex<T>*>* ll = linkedlist.getHead();
while(ll != NULL)
{
//iterate the list of edges
LinkedListNode< Edge<T> >* llEdges = ll->data->getEdges().getHead();
while(llEdges != NULL){
Vertex<T>* pv = llEdges->data.getTo();
if (pv == vertex)
{
count++;
}
llEdges = llEdges->next;
}
ll = ll->next;
}//end while
return count;
}
//Returns the outdegree of the vertex v. Throw
//an illegal argument exception if the argument does not correspond to an existing vertex.
int outdegree(string v){
Vertex<T>* vertex = hashtable.get(v);
if (vertex == NULL)
{
throw IllegalArgumentException();
}
return vertex->getOutdegree();
}
//Returns the number of edges of the vertex v.
int edgeCount(string v){
Vertex<T>* vertex = hashtable.get(v);
if (vertex == NULL)
{
throw IllegalArgumentException();
}
return vertex->getEdges().size();
}
//Returns the number of edges in the graph
int edgeCount(){
LinkedList<Vertex<T>*> linkedlist;
hashtable.getVertices(linkedlist);
int count = 0;
//iterate the list
LinkedListNode<Vertex<T>*>* ll = linkedlist.getHead();
while(ll != NULL)
{
count += ll->data->getEdges().size();
ll = ll->next;
}
return count;
}
//Returns the weight
//of the edge connecting vertices u and v. If the vertices are the same, return 0.
//If the vertices are not adjacent, return infinity (your representation of infinity).
//Throw an illegal argument exception if the arguments do not correspond to
//existing vertices.
double adjacent( string u, string v ){
Vertex<T>* pu = hashtable.get(u);
Vertex<T>* pv = hashtable.get(v);
if (pv == NULL || pu == NULL)
{
throw IllegalArgumentException();
}
//iterate the list
LinkedListNode< Edge<T> >* ll = pu->getEdges().getHead();
while(ll != NULL)
{
if (ll->data.getTo() == pv)
{
return ll->data.getWeight();
}
ll = ll->next;
}
return INFINITY;
}
//Performs DFS traversal starting on vertex v.
//Reset vertices after the traversal.
void DFS(string v){
Vertex<T>* pv = hashtable.get(v);
if (pv == NULL)
{
throw IllegalArgumentException();
}
LinkedStack<Vertex<T>*> stack;
stack.push(pv);
while (!stack.isEmpty())
{
Vertex<T> *u = NULL;
try{
u = stack.pop();
}catch(StackEmptyException &e){
cout << e.what() << endl;
}
if (!u->isVisited())
{
u->setVisited(true);
//visit it
cout << u->getName() << " " << u->getData() << endl;
//check its neigbours
//iterate the list
LinkedListNode< Edge<T> >* llEdges = u->getEdges().getHead();
while(llEdges != NULL){
if (llEdges->data.getTo()->isVisited() == false)
{
stack.push(llEdges->data.getTo());
}
llEdges = llEdges->next;
}
}
}//end while
//Reset vertices after the traversal.
reset();
}
//Performs BFS traversal starting on vertex v.
//Reset vertices after the traversal.
void BFS(string v){
Vertex<T>* pv = hashtable.get(v);
if (pv == NULL)
{
throw IllegalArgumentException();
}
LinkedQueue<Vertex<T>*> queue;
queue.enqueue(pv);
while (!queue.isEmpty())
{
Vertex<T> *u = NULL;
try{
u = queue.dequeue();
}catch(QueueEmptyException &e){
cout << e.what() << endl;
}
if (!u->isVisited())
{
u->setVisited(true);
//visit it
cout << u->getName() << " " << u->getData() << endl;
//check its neigbours
//iterate the list
LinkedListNode< Edge<T> >* llEdges = u->getEdges().getHead();
while(llEdges != NULL){
if (!llEdges->data.getTo()->isVisited())
{
queue.enqueue(llEdges->data.getTo());
}
llEdges = llEdges->next;
}
}
}//end while
//Reset vertices after the traversal.
reset();
}
//Determines if u and v are connected
bool isConnected(Vertex<T>* v, Vertex<T>* u){
LinkedList< Vertex<T>* > visitedList;
LinkedList< Vertex<T>* > ll;
ll.add(v);
while (ll.size() > 0)
{
Vertex<T>* temp = ll.getHead()->data;
ll.remove(ll.getHead()->data);
visitedList.add(temp);
//iterate the list
LinkedListNode< Edge<T> >* llEdges = temp->getEdges().getHead();
while(llEdges != NULL){
Vertex<T>* pv = llEdges->data.getTo();
if (pv == u)
{
return true;
}
if (visitedList.contains(pv) == false)
{
ll.add(pv);
}
llEdges = llEdges->next;
}
}
return false;
}
//find the vertex that has next min key (distance)
//set the new key(distance) if it is shorter
Vertex<T>* processNextMinVertex(Vertex<T>* current){
Vertex<T>* u = NULL;
//iterate neibours from current
LinkedListNode< Edge<T> >* llEdge = current->getEdges().getHead();
while (llEdge != NULL)
{
u = llEdge->data.getTo();
double newKey = current->getKey() + llEdge->data.getWeight() ;
if (u->isVisited() == false)
{
if (newKey < u->getKey())
{
u->setKey(newKey);
u->setPrevVertex(current);
}
}
llEdge = llEdge->next;
}
double min = INFINITY;
LinkedList<Vertex<T>*> linkedlist;
hashtable.getVertices(linkedlist);
//find min unvisited node
//iterate that list of vertice
LinkedListNode<Vertex<T>*>* ll = linkedlist.getHead();
while (ll != NULL)
{
if (ll->data->isVisited() == false && min > ll->data->getKey())
{
min = ll->data->getKey();
u = ll->data;
}
ll = ll->next;
}
return u;
}
//shortPath( string u, string v ) (20 points) Returns the shortest path
//between vertices u and v. Throw an illegal argument exception if the arguments
//do not correspond to existing vertices.
void shortPath(string u, string v){
reset();//reset
//reset previous vertices
resetPrevVertices();
Vertex<T>* pu = hashtable.get(u);
if (pu == NULL)
{
throw IllegalArgumentException();
}
Vertex<T>* pv = hashtable.get(v);
if (pv == NULL)
{
throw IllegalArgumentException();
}
//check if them connected
if (!isConnected(pu, pv))
{
cout << "Vertices are not connected" << endl;
throw IllegalArgumentException();
}
Vertex<T>* current = pu; //current checking vertex
Vertex<T>* nextVertex; //next min vertex
current->setKey(0);//starting vertex
while (current != pv)
{
current->setVisited(true);
nextVertex = processNextMinVertex(current);
current = nextVertex;
}//end while
//print shortest path
stringstream ss;
ss << current->getName() << " " << current->getData();
current = current->getPrevVertex();
//iterate to source
while (current != NULL)
{
ss << " -> " << current->getName() << " " << current->getData();
current = current->getPrevVertex();
}
//print path
cout << ss.str() << endl;
//Reset vertices
reset();
}
//Returns the shortest
//distance between vertices u and v. Throw an illegal argument exception if the
//arguments do not correspond to existing vertices. The distance between a vertex
//and itself is 0.0. The distance between vertices that are not connected is innity.
double distance( string u, string v ){
reset();//reset
//reset previous vertices
resetPrevVertices();
Vertex<T>* pu = hashtable.get(u);
if (pu == NULL)
{
throw IllegalArgumentException();
}
Vertex<T>* pv = hashtable.get(v);
if (pv == NULL)
{
throw IllegalArgumentException();
}
//check if them connected
if (!isConnected(pu, pv))
{
cout << "Vertices are not connected" << endl;
throw IllegalArgumentException();
}
Vertex<T>* current = pu; //current checking vertex
Vertex<T>* nextVertex; //next min vertex
current->setKey(0);//starting vertex
while (current != pv)
{
current->setVisited(true);
nextVertex = processNextMinVertex(current);
current = nextVertex;
}//end while
double shortestDistance = current->getKey();
//Reset vertices
reset();
return shortestDistance;
}
///////////////////////////Mutators///////////////////
//Reads structure from a text file and builds a undirected weighted graph.
void buildGraph(string filename){
ifstream infile;
//data of file
int numberOfVertices; //number of vertices
int numberOfEdges; //number of edges
string name; //name of vertex
double data; //data of vertex
string from, to; //for edge
double weight;
//open file for reading
infile.open(filename.c_str());
//check input file
if(infile.fail())
{
cerr << "Could not open the file " << filename << endl;
return;
}
//read first 2 numbers
infile >> numberOfVertices;
infile >> numberOfEdges;
//read the vertices
for (int i = 0; i < numberOfVertices; i++)
{
infile >> name;
infile >> data;
hashtable.put(new Vertex<double>(name, data));
}//end for
//read the edges
for (int i = 0; i < numberOfEdges; i++)
{
infile >> from;
infile >> to;
infile >> weight;
try{
insert(from, to, weight);
}catch(IllegalArgumentException &e){
cout << e.what() << endl;
}
}//end for
//close input file
infile.close();
numVertices = numberOfVertices;
}
//Removes all the elements in the undirected weighted graph
void clear(){
numVertices = 0;
hashtable.clear();
}
//Iterates over all vertices in the graph and marks them
//as unvisited.
void reset(){
//iterate the list
LinkedList<Vertex<T>*> linkedlist;
hashtable.getVertices(linkedlist);
LinkedListNode<Vertex<T>*>* ll = linkedlist.getHead();
while(ll != NULL)
{
ll->data->setVisited(false);
ll->data->setKey(INFINITY);
ll = ll->next;
}
}
//Iterates over all vertices in the graph and reset previous vertex
void resetPrevVertices(){
//iterate the list
LinkedList<Vertex<T>*> linkedlist;
hashtable.getVertices(linkedlist);
LinkedListNode<Vertex<T>*>* ll = linkedlist.getHead();
while(ll != NULL)
{
ll->data->setPrevVertex(NULL);
ll = ll->next;
}
}
//If the weight w < 0
//or w = 1, throw an illegal argument exception. If the weight w is 0, remove
//any edge between u and v (if any). Otherwise, add an edge between vertices u
//and v with weight w. If an edge already exists, replace the weight of the edge
//with the new weight. If the vertices do not exist or are equal, throw an illegal
//argument exception.
void insert(string u, string v, double w){
if (w < 0 || w == 1)
{
throw IllegalArgumentException();
}
Vertex<T>* pu = hashtable.get(u);
Vertex<T>* pv = hashtable.get(v);
//If the vertices do not exist or are equal, throw an illegal
//argument exception.
if (pv == NULL || pu == NULL || pv == pu)
{
throw IllegalArgumentException();
}
if (w == 0)//remove edge
{
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@invalid initialization of non-const reference of type 'Edge<double>&' from an rvalue of type 'Edge<double>'
pu->getEdges().remove(Edge<T>(pu, pv, 0));
}else{
//add edge
pu->getEdges().add(Edge<T>(pu, pv, w));
}
}
//Removes vertex v from the graph, and updates
//connections in the graph.
void del(string v){
Vertex<T>* pv = hashtable.get(v);
//If the vertex do not exist throw an illegal
//argument exception.
if (pv == NULL)
{
throw IllegalArgumentException();
}
hashtable.del(v);
}
private:
Hashtable<T> hashtable;
int numVertices;
};
#endif
Main.cpp:
/*
The program implements the menu based program
that allows user to use graph functions
*/
#include <iostream>
#include <string>
#include "Graph.h"
#include <ctime>
#include <cstdlib>
#include <sstream>
using namespace std;
//read an integer
int readInt(string prompt){
string input;
stringstream ss;
//prompt for input
cout << prompt;
getline(cin, input);
//push to stream
ss << input;
int intNumber;
ss >> intNumber;
return intNumber;
}
//read a double
double readDouble(string prompt){
string input;
stringstream ss;
//prompt for input
cout << prompt;
getline(cin, input);
//push to stream
ss << input;
double intNumber;
ss >> intNumber;
return intNumber;
}
//build graph from text file
void buildGraph(Graph<double> &graph){
string filename = "input.txt";
//cout << "Enter the file name: ";
//getline(cin, filename);
graph.buildGraph(filename);
}
int main(){
string name, name2; //name of vertex
Graph<double> MSTGraph; //minimum spanning tree
//define graph
Graph<double> graph;
int option = -1;
//build graph
try{
buildGraph(graph);
}catch(IllegalArgumentException &e){
cout << e.what() << endl;
}
while (option != 0)
{
//display menu
cout << "1. Check empty" << endl;
cout << "2. Get indegree" << endl;
cout << "3. Get outdegree" << endl;
cout << "4. Edge count of graph" << endl;
cout << "5. DFS" << endl;
cout << "6. BFS" << endl;
cout << "7. shortest path" << endl;
cout << "8. distance" << endl;
cout << "0. Exit" << endl;
option = readInt("Your selection? ");
switch (option)
{
case 1://Check empty
cout << "Graph is empty?" << graph.empty() << endl;
break;
case 2://Get indegree
cout << "Enter name: ";
getline(cin, name);
try{
cout << "Degree = " << graph.indegree(name);
}catch(IllegalArgumentException &e){
cout << e.what() << endl;
}
break;
case 3://Get outdegree
cout << "Enter name: ";
getline(cin, name);
try{
cout << "Degree = " << graph.outdegree(name);
}catch(IllegalArgumentException &e){
cout << e.what() << endl;
}
break;
case 4://Edge count of graph
cout << "Edge count of graph = " << graph.edgeCount() << endl;
break;
case 5://DFS
cout << "Enter name: ";
getline(cin, name);
try{
graph.DFS(name);
}catch(IllegalArgumentException &e){
cout << e.what() << endl;
}
break;
case 6://BFS
cout << "Enter name: ";
getline(cin, name);
try{
graph.BFS(name);
}catch(IllegalArgumentException &e){
cout << e.what() << endl;
}
break;
case 7://short path
cout << "Enter first name: ";
getline(cin, name);
cout << "Enter second name: ";
getline(cin, name2);
try{
graph.shortPath(name, name2);
}catch(IllegalArgumentException &e){
cout << e.what() << endl;
}
break;
case 8://distance
cout << "Enter first name: ";
getline(cin, name);
cout << "Enter second name: ";
getline(cin, name2);
try{
cout << "The shortest distance is " << graph.distance(name, name2) << endl;
}catch(IllegalArgumentException &e){
cout << e.what() << endl;
}
break;
case 0:
break;
default:
cout << "Invalid selection" << endl;
break;
}
cout << endl << endl;
}
return 0;
}