问题
I am writing a program that will read in a list of names with social security numbers (not real ones of course) and sort the list based on either last name or ssn, depending on a command line argument. I have overloaded the < operator and also overloaded input and output operators for simplicity. Everything compiles fine until I add the sort function and the output at the end of main. I'm stumped. Any ideas? Any other tips are also greatly appreciated.
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <fstream>
using namespace std;
enum sortVar { NAME, SOCSEC };
class record {
public:
friend bool operator<(record& rhs, record& name);
friend ostream& operator<<(ostream& out, record& toWrite);
friend istream& operator>>(istream& in, record& toRead);
bool t_sort;
private:
string firstName, lastName, ssn;
};
bool operator<(record& rhs, record& next)
{
if (rhs.t_sort = false) {
if (rhs.lastName == next.lastName)
return rhs.firstName < next.firstName;
else
return rhs.lastName < next.lastName;
}
else if (rhs.t_sort = true)
return rhs.ssn < next.ssn;
}
ostream& operator<<(ostream& out, record& toWrite)
{
out << toWrite.lastName
<< " "
<< toWrite.firstName
<< " "
<< toWrite.ssn;
}
istream& operator>>(istream& in, record& toRead)
{
in >> toRead.lastName >> toRead.firstName >> toRead.ssn;
}
int main(int argc, char* argv[])
{
if (argc !=3) {
cerr << "Incorrect number of arguments.\n";
exit(1);
}
if (argv[1] != "name" || argv[1] != "socsec") {
cerr << "Argument 1 must be either 'name' or 'socsec'.\n";
exit(1);
}
sortVar sortMode;
if (argv[1] == "name")
sortMode = NAME;
else if (argv[1] == "socsec")
sortMode = SOCSEC;
ifstream fin(argv[2]);
vector<record> nameList;
while(!fin.eof()) {
record r;
if (sortMode == NAME)
r.t_sort = false;
else if (sortMode == SOCSEC)
r.t_sort = true;
fin >> r;
nameList.push_back(r);
}
//sort(nameList.begin(), nameList.end());
//cout << nameList;
}
回答1:
This is kind of strange, and something your compiler should warn about
if (rhs.t_sort = false)
You are not testing the value of t_sort
but always setting it to false.
Testing a bool
against true
or false
is bit unnecessary anyway, as this is what the if
-statement is doing already.
Try this code instead
bool operator<(const record& rhs, const record& next)
{
if (rhs.t_sort) {
return rhs.ssn < next.ssn;
}
else
{
if (rhs.lastName == next.lastName)
return rhs.firstName < next.firstName;
else
return rhs.lastName < next.lastName;
}
}
回答2:
Are you sure that having an ordering for your record
class has a real meaning, not only for arbitrary sorting purposes? Consider a class for large integers, where a such an ordering for your objects makes sense, but would it make such valid sense for your records? Or does it lose its meaning if you never sort?
[imo] Do not couple this ordering introduced by operator<
with your class definition unless it has a real correspondence with it, in other words, if it is intuitively clear for human beings that some "object a" is smaller than some "object b".
This holds especially true if you ever want to have different orderings for non intuitively order-able class objects, think of ascending vs. descendening, by first name, by last name, by number of cars, et cetera. Then nobody will remember what your default ordering is without looking up the documentation/code, thus loosing even its convenience.
Instead, either pass functors or in-place lambda function:
#include <algorithm>
#include <functional>
#include <vector>
struct Foo {
int x;
Foo (int x) : x(x) {}
};
struct FooAscending : std::binary_function<Foo,Foo, bool>
{
bool operator() (Foo const &lhs, Foo const &rhs) const {
return lhs.x < rhs.x;
}
};
int main () {
std::vector<Foo> foos;
foos.emplace_back(1);
foos.emplace_back(2);
sort (foos.begin(), foos.end(),
[](Foo const &l, Foo const &r) { return l.x < r.x; });
sort (foos.begin(), foos.end(),
[](Foo const &l, Foo const &r) { return l.x > r.x; });
sort (foos.begin(), foos.end(), FooAscending());
}
来源:https://stackoverflow.com/questions/9336579/overloading-comparison-operators-to-work-with-stl-sort-in-c