linux中的c++编译错误

Posted

技术标签:

【中文标题】linux中的c++编译错误【英文标题】:c++ compilation error in linux 【发布时间】:2016-07-18 20:10:02 【问题描述】:

我的代码在带有 Visual Studio 的 Windows 环境中运行,但似乎无法在 Linux 中编译。我已经排除故障很长时间了,但我终其一生都无法找出问题所在。

我的程序中的错误为“错误:从'Edge'类型的右值对'Edge&'类型的非常量引用的无效初始化

我不明白为什么 Linux 似乎有问题,因为它确实在 Windows 环境中编译,所以它在语法上并不错误。我需要改变什么才能让这个东西在 Linux 上运行?

我已经包含了我认为是其中一个程序的相关代码,链接中的第一个,因为另一个有相同的错误。

编辑:我正在使用 g++ 在 Linux 中编译我的代码。如果您需要任何其他信息,请告诉我,因为根据错误消息和我对 Linux 的缺乏经验,我不知道哪些信息可能相关。

命令行错误:http://imgur.com/a/OlqY8

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;

【问题讨论】:

没有时间在您的代码中找到它,但它适用于 MSVS,因为 evil extension 请不要链接编译器错误的图像 - 只需复制/粘贴错误的文本,并将其直接包含在您的问题中。 【参考方案1】:

如果不了解更多信息,很难回答这样的问题。例如,如果您使用不同的编译器来完成这项工作,它甚至可能与 Linux 无关。

您的整个工具链是什么?你在使用 GCC 吗? G++?明威?

另外,您确定错误发生在您提供的代码中,而不是其中一个包含的文件中吗?

话说回来……

这是一个很好的左值和右值explanation,也许阅读 c++11 后特性的特性可能会帮助你缩小问题范围,并找出代码在 Linux 中的确切位置,让我们有更好的能力来帮助您。

【讨论】:

以上是关于linux中的c++编译错误的主要内容,如果未能解决你的问题,请参考以下文章

C++ Linux 到 Windows 交叉编译错误

无法使用 gcc 在 Linux 中编译任何 c++ 程序,出现一些奇怪的错误 [重复]

尝试在 Linux Mint 17.1 64 位(未声明/非类型)上“制作”C++ 项目时从 cstdlib 编译错误和类似错误

错误:在 Linux 上使用 OpenGL 编译 C++ 程序时出现“GL/glfw3.h:没有这样的文件或目录”

C++编译链接错误

使用赋值运算符 =? 时 C++ 中的编译错误