Been working on this for hours now. but most of it has been trying to fix these two errors. I've been googling my heart out and keep getting cryptic answers about the const. Really need help. it's supposed to take in names of students and their scores, sort them, then display. if i comment out the sort function call it builds and runs fine...but with sort uncommented i get this error:

**** Build of configuration Debug for project StudentScores ****

**** Internal Builder is used for build               ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc/Student.o ../src/Student.cpp
../src/Student.cpp: In function ‘bool operator<(const Student&, const Student&)’:
../src/Student.cpp:25: error: passing ‘const Student’ as ‘this’ argument of ‘int Student::getscore()’ discards qualifiers
../src/Student.cpp:25: error: passing ‘const Student’ as ‘this’ argument of ‘int Student::getscore()’ discards qualifiers
Build error occurred, build is stopped
Time consumed: 161  ms.

Here are the three project files. and in case it helps, i'm using eclipse CDT on ubuntu.

/*
 * StudentDriver.cpp
 *
 *  Created on: Jun 1, 2010
 *      Author: rootchord
 */

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#include "Student.h"
int size;

int main(){
vector<Student> roster;

cout << "How many students do you want to enter?" << endl;
cin >> size;
Student input[size];
string _name;
int _score;

for(int i=0;i<size;i++){
	cout << "Enter student name:" << endl;
	cin >> _name;
	input[i].setname(_name);

	cout << "Enter the student's score:" << endl;
	cin >> _score;
	input[i].setscore(_score);

	roster.push_back(input[i]);
}

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

vector<Student>::iterator p = roster.begin();
for(int i=0;i<size;i++){
	cout << p->getname()<< " got a score of " << p->getscore() << endl;p++;
}

return 0;
}
/*
 * Student.h
 *
 *  Created on: Jun 1, 2010
 *      Author: rootchord
 */

#ifndef STUDENT_H_
#define STUDENT_H_


class Student {
public:
	void setname(string);
	void setscore(int);
	string getname();
	int getscore();
    friend bool operator <(const Student&, const Student&);
private:
	string name;
	int score;
};

#endif /* STUDENT_H_ */
/*
 * Student.cpp
 *
 *  Created on: Jun 1, 2010
 *      Author: rootchord
 */
#include<string>
using namespace std;
#include "Student.h"


void Student::setname(string _name){
	name = _name;
}

void Student::setscore(int _score){
	score = _score;
}

string Student::getname(){return name;}

int Student::getscore(){return score;}

 bool operator< (const Student& first, const Student& second){
	return (first.getscore() < second.getscore());
}

Recommended Answers

All 6 Replies

There is a third parameter to std::sort() which is the name of a comparison function that you will write. That is not necessary if you have a vector of standard data types, such as int, double and std::string. Anything more complex such as a c++ class that you created will require the comparison function. See the example program at this link.

Remove the const modifiers from your friend function, and it will work.

I understand your desire to protect those parameters passed by reference, that seems to be the problem here.

AD- sort( ) can be called with just the start and end iterators, I assume it makes use of the < operator if no comparison function is provided.

(Using VC++ 2008)

If i remove the const's i get this error:

**** Build of configuration Debug for project StudentScores ****

**** Internal Builder is used for build               ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc/Student.o ../src/Student.cpp
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc/StudentDriver.o ../src/StudentDriver.cpp
In file included from /usr/include/c++/4.4/algorithm:62,
                 from ../src/StudentDriver.cpp:9:
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&) [with _Tp = Student]’:
/usr/include/c++/4.4/bits/stl_algo.h:2268:   instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student, std::allocator<Student> > >, _Size = int]’
/usr/include/c++/4.4/bits/stl_algo.h:5220:   instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Student*, std::vector<Student, std::allocator<Student> > >]’
../src/StudentDriver.cpp:36:   instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:89: error: no match for ‘operator<’ in ‘__a < __b’
../src/Student.h:18: note: candidates are: bool operator<(Student&, Student&)
/usr/include/c++/4.4/bits/stl_algo.h:90: error: no match for ‘operator<’ in ‘__b < __c’
../src/Student.h:18: note: candidates are: bool operator<(Student&, Student&)
/usr/include/c++/4.4/bits/stl_algo.h:92: error: no match for ‘operator<’ in ‘__a < __c’
../src/Student.h:18: note: candidates are: bool operator<(Student&, Student&)
/usr/include/c++/4.4/bits/stl_algo.h:96: error: no match for ‘operator<’ in ‘__a < __c’
../src/Student.h:18: note: candidates are: bool operator<(Student&, Student&)
/usr/include/c++/4.4/bits/stl_algo.h:98: error: no match for ‘operator<’ in ‘__b < __c’
../src/Student.h:18: note: candidates are: bool operator<(Student&, Student&)
Build error occurred, build is stopped
Time consumed: 634  ms.

>>AD- sort( ) can be called with just the start and end iterators, I assume it makes use of the < operator if no comparison function is provided.

Isn't that what I just said??? But it only works on POD and std::string. most everything else will require the third parameter.

In function ‘bool operator<(const Student&, const Student&)’:
../src/Student.cpp:25: error: passing ‘const Student’ as ‘this’ argument of ‘int Student::getscore()’ discards qualifiers

Your compiler is trying to tell you that you want to declare the getscore() and getname() methods as const .
So, instead of stripping away constness, you might rather add some more, like so ..

class Student {
...
  string getname() const;
  int getscore() const;
  friend bool operator <(const Student&, const Student&);
...
};
// and
...
string Student::getname() const {return name;}
int Student::getscore() const {return score;}
...

Then again, since the operator < overload is a friend, you can write it without calling the member methods at all ..

bool operator< (const Student& first, const Student& second){
  // Directly access the member variables ..
  return (first.score < second.score);
}

I.e. in this case, you actually could do without declaring the getxxxx() methods const, but I'd suggest that you declare them as const - regardless of how you write the operator < overload.

In main(), you are using GCC's variable length array extension (Student input), it is not standard C++ and you could very easily do without it..

int main()
{
  // size is not a global variable anymore
  int size;
  cout << "How many students do you want to enter?" << endl;
  cin >> size;
  //// Non-standard array not used at all
  //// Student input[size];
  // This gives you a properly sized vector ..
  vector<Student> roster(size);
  
  string _name;
  int _score;

  for(int i=0;i<size;i++){
    cout << "Enter student name:" << endl;
    cin >> _name;
    //// input[i].setname(_name);
    roster[i].setname(_name);

    cout << "Enter the student's score:" << endl;
    cin >> _score;
    //// input[i].setscore(_score);
    roster[i].setscore(_score);
    
    //// push_back() not needed
    //// roster.push_back(input[i]);
  }
...

PS. If you want to know whether you are writing standards-compliant C++ code, pass e.g. the following arguments to g++:

-std=c++98 -pedantic-errors

Thanks so much everyone! that worked out great! I'm pretty stubborn and i like figuring stuff out myself, but it's nice to know there's at least one group of friendly software engineers i can go to in a desperate time. thanks again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.