std :: sort и бинарный оператор '=' проблема со структурой C ++ - PullRequest
2 голосов
/ 05 августа 2009

Хорошо ... У меня есть эта структура и функция сравнения-

struct Edge
{
          char point1;  
          char point2;  
          int weight;   

          bool operator<( const Edge& rhs ) const
          {
              return( weight < rhs.weight );
          }
}; //end Edge

bool compareEdge( const Edge& lhs, const Edge& rhs )
{
      return( lhs.weight < rhs.weight );
}

У меня есть вектор, объявленный как ...

vector<Edge> edges;

Наконец, я пытаюсь отсортировать, используя оператор

sort( edges.begin(), edges.end() );

и я получаю следующую ошибку в Visual Studio 2005 ...

------ Build started: Project: RadakovichLab6, Configuration: Debug Win32 ------ Compiling... graph.cpp c:\program files\microsoft visual studio 8\vc\include\algorithm(2981) : error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const Edge' (or there is no acceptable conversion)
c:\documents and settings\jake\my documents\visual studio 2005\projects\radakovichlab6\graph.h(25): could be 'Edge &Edge::operator =(const Edge &)'
while trying to match the argument list '(const Edge, Edge)'
c:\program files\microsoft visual studio 8\vc\include\algorithm(2997) : see reference to function template instantiation 'void std::_Insertion_sort1<_BidIt,Edge>(_BidIt,_BidIt,_Ty*)' being compiled
with
[
    _BidIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>>,
    _Ty=Edge
]
c:\program files\microsoft visual studio 8\vc\include\algorithm(3105) : see reference to function template instantiation 'void std::_Insertion_sort<_RanIt>(_BidIt,_BidIt)' being compiled
with
[
    _RanIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>>,
    _BidIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>>
]
c:\program files\microsoft visual studio 8\vc\include\algorithm(3112) : see reference to function template instantiation 'void std::_Sort<std::_Vector_const_iterator<_Ty,_Alloc>,__w64 int>(_RanIt,_RanIt,_Diff)' being compiled
with
[
    _Ty=Edge,
    _Alloc=std::allocator<Edge>,
    _RanIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>>,
    _Diff=__w64 int
]
c:\documents and settings\jake\my documents\visual studio 2005\projects\radakovichlab6\graph.cpp(107) : see reference to function template instantiation 'void std::sort<std::_Vector_const_iterator<_Ty,_Alloc>>(_RanIt,_RanIt)' being compiled
with
[
    _Ty=Edge,
    _Alloc=std::allocator<Edge>,
    _RanIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>>
] c:\program files\microsoft visual studio 8\vc\include\algorithm(2988) : error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const Edge' (or there is no acceptable conversion)
c:\documents and settings\jake\my documents\visual studio 2005\projects\radakovichlab6\graph.h(25): could be 'Edge &Edge::operator =(const Edge &)'
while trying to match the argument list '(const Edge, const Edge)' c:\program files\microsoft visual studio 8\vc\include\algorithm(2989) : error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const Edge' (or there is no acceptable conversion)
c:\documents and settings\jake\my documents\visual studio 2005\projects\radakovichlab6\graph.h(25): could be 'Edge &Edge::operator =(const Edge &)'
while trying to match the argument list '(const Edge, Edge)' Generating Code... Compiling... main.cpp Generating Code... Build log was saved at "file://c:\Documents and Settings\Jake\My Documents\Visual Studio 2005\Projects\RadakovichLab6\Debug\BuildLog.htm" RadakovichLab6 - 3 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Вопрос в первой строке ошибки. Я получаю эту ошибку, использую ли я перегруженный оператор <или передаю функцию сравнения в функцию std :: sort. Я думаю, что оператора присваивания структуры Edge по умолчанию должно быть достаточно, поскольку нет динамически выделяемой памяти. Если у кого-то есть понимание, я был бы благодарен. </p>

полный код ...

        #include <list>
        #include <map>
        #include <queue>
        #include <vector>
        #include <algorithm>
        #include <iostream>

        using namespace std;

        //the Edge and aGraph together represent the adjacency list
        //representation of a graph.
        struct Edge
        {
            char point1;  //this represents the endpoint of an edge
            char point2;  
            int weight;   //this is the weight of the edge

            bool operator<( const Edge& rhs ) const
            {
                return( weight < rhs.weight );
            }
        }; //end Edge

        class Graph
        {
        public:
            //Default constructor
            Graph();

            //This method inputs an edge into a graph.
            void inputEdge( char pointA, char pointB, int wt )
            {
                //used to input the edges of the graph
            Edge anEdge;

            //prepare for insertion into list
            anEdge.point1 = pointA;
            anEdge.point2 = pointB;
            anEdge.weight = wt;

            edges.push_back( anEdge );

            //insert edge into the adjacency list.
            aGraph[pointA].push_front( pointB );

            //insert the opposite direction into the
            //adjacency list.
            aGraph[pointB].push_front( pointA )
             }

             //This...
             void bfs();

            //This prints a graph and is used only for debugging purposes.
            void printGraph() const
            {

             list<char>::const_iterator listIter;
             map<char, list<char>>::const_iterator mapIter;

             for( mapIter = aGraph.begin(); 
              mapIter != aGraph.end();
              mapIter++ )
             {
                for( listIter = mapIter->second.begin();
                         listIter != mapIter->second.end();
                         listIter++ )
               {
                     cout << mapIter->first << " " << *listIter << endl;
               } //end for
             } //end for


             sort( edges.begin(), edges.end() );

             vector<Edge>::const_iterator vectIt;

             for( vectIt = edges.begin();
                  vectIt != edges.end();
                  vectIt++ )
             {
                cout << vectIt->point1 << " " << vectIt->point2 << " " << vectIt->weight << endl;
              } //end for
         } //end printGraph


        private:
            //This is the adjacency list
            map<char, list<char>> aGraph;

            //This is a list of edges and their weights.
            vector<Edge> edges;
        };  //end Graph

int main()
{

    Graph myGraph;

    myGraph.inputEdge( 'O', 'A', 2 );
    myGraph.inputEdge( 'O', 'B', 5 );
    myGraph.inputEdge( 'O', 'C', 4 );
    myGraph.inputEdge( 'A', 'B', 2 );
    myGraph.inputEdge( 'A', 'D', 7 );
    myGraph.inputEdge( 'B', 'D', 4 );
    myGraph.inputEdge( 'B', 'E', 3 );
    myGraph.inputEdge( 'C', 'B', 1 );
    myGraph.inputEdge( 'C', 'E', 4 );
    myGraph.inputEdge( 'E', 'D', 1 );
    myGraph.inputEdge( 'D', 'T', 5 );
    myGraph.inputEdge( 'E', 'T', 7 );
    myGraph.inputEdge( 'G', 'Z', 8 );

    myGraph.printGraph();

    cout << endl << endl;

    system("PAUSE");
    return 0;
} //end main

Вот код ...

Ответы [ 5 ]

4 голосов
/ 05 августа 2009

Вы работаете с const vector, который не может быть отсортирован. (Или изменилось).

Это потому, что ваша функция const:

void printGraph() const

Удалите const, чтобы члены вашего класса могли быть изменены (и, следовательно, отсортированы).

3 голосов
/ 05 августа 2009

Следующий код компилируется под g ++ 4.4.0:

#include <algorithm>
#include <vector>
using namespace std;

struct Edge {
    char point1;  
    char point2;  
    int weight;   

    bool operator<( const Edge& rhs ) const {
        return( weight < rhs.weight );
    }
}; 

bool compareEdge( const Edge& lhs, const Edge& rhs ) {
      return( lhs.weight < rhs.weight );
}

int main() {
    vector <Edge> edges;
    sort( edges.begin(), edges.end() );
}

Пожалуйста, проверьте это с вашим компилятором. В целом, было бы полезно, если бы вы и другие опубликовали такие маленькие законченные программы, которые можно легко протестировать и которые иллюстрируют проблему (или ее отсутствие в данном случае).

0 голосов
/ 05 августа 2009

Функция printGraph объявлена ​​как постоянная функция-член Graph, но вы пытаетесь изменить переменную-член (вектор ребер). Удалите const из объявления printGraph, и код скомпилируется.

Либо создайте локальную копию вектора ребер и отсортируйте ее перед печатью, поскольку в комментариях говорится, что эта функция предназначена только для производительности отладки, и это не должно вызывать особого беспокойства. Это немного вводит в заблуждение, что функция printGraph все равно изменяет вектор ребер.

0 голосов
/ 05 августа 2009

Мне кажется, что вы звоните std::sort с std::vector<Edge>::const_iterator вместо std::vector<Edge>::iterator, вероятно, в graph.cpp строке 107.

После просмотра кода: Итераторы действительно постоянны. edges является переменной-членом Graph, а printGraph является методом const. Следовательно, edges нельзя изменить внутри printGraph, поскольку объект Graph нельзя изменить методом const. Сортировка edges изменит его, что приведет к ошибке компиляции.

0 голосов
/ 05 августа 2009

Приведенный выше код прекрасно компилируется, похоже, у вас есть проблема с назначением при попытке назначить что-либо для const Edge.

Вам не нужно определять оператор присваивания, но вы не можете назначить что-либо для const Edge.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...