我已经掌握了这部分代码(可能未对包含的内容进行优化)
#include <iostream>
#include <string>
#include <map>
#include <list>
#include <vector>
#include <fstream>
using namespace std;
class CTurist {
string name;
int age;
public:
CTurist(string name, int age) {
this->name = name;
this->age = age;
}
CTurist() {}
int GetAge() const { return age; }
bool operator< (CTurist& right) {
return this->age < right.age && this->name < right.name;
}
friend fstream& operator>>(fstream& is, CTurist& turist) {
is >> turist.name >> turist.age;
return is;
}
friend fstream& operator<<(fstream& os, const CTurist& turist) {
os << turist.name << "\t" << turist.age;
return os;
}
};
class CHotel {
string name;
int rating;
int bedsCount;
map<CTurist, unsigned> mmap; //<Turist, dni prestoi>
public:
CHotel(string name, int rating, int bedsCount, fstream stream) {
this->name = name;
this->rating = rating;
this->bedsCount = bedsCount;
//read stream
}
CHotel(string name, int rating, int bedsCount) {
this->name = name;
this->rating = rating;
this->bedsCount = bedsCount;
}
CHotel() {}
void addRecord(pair<CTurist, unsigned> record) {
mmap.insert(record);
}
int GetCountTuristsInHotel() {
int count = 0;
for (map<CTurist, unsigned>::iterator it = mmap.begin(); it != mmap.end(); it++)
count += it->second;
return count;
}
CTurist GetMaxStayTurist() {
map<CTurist, unsigned>::iterator max = mmap.begin();
for (map<CTurist, unsigned>::iterator it = mmap.begin(); it != mmap.end(); it++)
if (it->second > max->second)
max = it;
return max->first;
}
float DaysToBedsRatio() {
float busyDaysCount = 0.0;
for (map<CTurist, unsigned>::iterator it = mmap.begin(); it != mmap.end(); it++)
busyDaysCount += it->second;
return busyDaysCount / bedsCount;
}
float AverageAge() {
float sumAge = 0.0;
for (map<CTurist, unsigned>::iterator it = mmap.begin(); it != mmap.end(); it++)
sumAge += (it->first).GetAge();
return sumAge / mmap.size();
}
list<CTurist> GetTuristByAge(int age) {
list<CTurist> llist;
for (map<CTurist, unsigned>::iterator it = mmap.begin(); it != mmap.end(); it++)
if (it->first.GetAge() == age)
llist.push_back(it->first);
return llist;
}
int GetTuristCountYongerThan(int age) {
int count = 0;
for (map<CTurist, unsigned>::iterator it = mmap.begin(); it != mmap.end(); it++)
if (it->first.GetAge() < age)
count++;
return count;
}
int GetTuristCountOlderThan(int age) {
int count = 0;
for (map<CTurist, unsigned>::iterator it = mmap.begin(); it != mmap.end(); it++)
if (it->first.GetAge() > age)
count++;
return count;
}
CTurist TheYongestTurist() {
CTurist turist = mmap.begin()->first;
for (map<CTurist, unsigned>::iterator it = mmap.begin(); it != mmap.end(); it++)
if (it->first.GetAge() < turist.GetAge())
turist = it->first;
return turist;
}
bool operator< (CHotel right) {
return this->rating < right.rating && this->bedsCount < right.bedsCount;
}
friend fstream& operator>> (fstream& is, CHotel& hotel) {
int count, n;
CTurist turist;
is >> hotel.name >> count;
for (int i = 0; i < count; i++) {
is >> turist >> n;
hotel.mmap.insert(pair<CTurist, unsigned>(turist, n));
}
is >> n; //reading the new line
return is;
}
friend fstream& operator<<(fstream& os, CHotel& hotel) {
os << hotel.name << "\t" << hotel.mmap.size();
for (map<CTurist, unsigned>::iterator it = hotel.mmap.begin(); it != hotel.mmap.end(); it++) {
os << it->first << endl;
os << it->second << endl;
}
os << endl;
return os;
}
};
class CComplex {
string name;
vector<CHotel> hotels;
public:
CComplex(string name, string filePath) {
fstream file;
file.open(filePath, ios::in);
if (!file) {
cout << "Unable to open file for reading..\n";
exit(3);
}
this->name = name;
CHotel hotel;
while (!file.eof()) {
file >> hotel;
hotels.push_back(hotel);
}
}
CComplex() {
}
CHotel TheBusiestOne() {
CHotel busiest = *hotels.begin();
float ratio = busiest.DaysToBedsRatio();
for (vector<CHotel>::iterator it = hotels.begin(); it != hotels.end(); it++)
if (it->DaysToBedsRatio() > ratio) {
busiest = *it;
ratio = busiest.DaysToBedsRatio();
}
return busiest;
}
float RatioOfAllHotels() {
float sum = 0;
for (vector<CHotel>::iterator it = hotels.begin(); it != hotels.end(); it++)
sum += it->DaysToBedsRatio();
return sum / hotels.size();
}
int TuristsOlderThan(int age) {
int count = 0;
for (vector<CHotel>::iterator it = hotels.begin(); it != hotels.end(); it++)
count += it->GetTuristCountOlderThan(age);
return count;
}
CHotel YongestAverageTurists() {
CHotel hotel = *hotels.begin();
for (vector<CHotel>::iterator it = hotels.begin(); it != hotels.end(); it++)
if (it->AverageAge() < hotel.AverageAge())
hotel = *it;
return hotel;
}
CTurist TheYongestTurist() {
CTurist turist = hotels.begin()->TheYongestTurist();
for (vector<CHotel>::iterator it = hotels.begin(); it != hotels.end(); it++)
if (it->TheYongestTurist().GetAge() < turist.GetAge())
turist = it->TheYongestTurist();
return turist;
}
void WriteToFile(string filePath) {
fstream file;
file.open(filePath, ios::out);
if (!file) {
cout << "Unable to open file for writing..\n";
exit(3);
}
file << name << "\t" << hotels.size();
for (vector<CHotel>::iterator it = hotels.begin(); it != hotels.end(); it++)
file << *it << endl;
file.close();
}
void addHotel(CHotel hotel) {
hotels.push_back(hotel);
}
friend fstream& operator<<(fstream& ostream, CComplex complex) {
ostream << complex.name << "\t" << complex.hotels.size();
for (vector<CHotel>::iterator it = complex.hotels.begin(); it != complex.hotels.end(); it++)
ostream << *it << endl;
return ostream;
}
};
int main()
{
CComplex ccomplex;
CHotel hotel("Echolandia", 5, 100);
//Name Years Nights
hotel.addRecord(pair<CTurist, unsigned>(CTurist("Echo", 23), 20));
hotel.addRecord(pair<CTurist, unsigned>(CTurist("Kristiyan", 25), 30));
ccomplex.addHotel(hotel);
hotel = CHotel("newHotelValey", 3, 20);
//Name Years Nights
hotel.addRecord(pair<CTurist, unsigned>(CTurist("Echo1", 12), 20));
hotel.addRecord(pair<CTurist, unsigned>(CTurist("Kristiyan1", 15), 30));
hotel.addRecord(pair<CTurist, unsigned>(CTurist("Kristiyan2", 30), 30));
ccomplex.addHotel(hotel);
fstream file;
file.open("test.txt", ios::out);
file << ccomplex;
}
问题是,如果我在CHotel中注释了两个函数,则没有编译错误,但是如果我得到其中一个,它将给出该错误。
Severity Code Description Project File Line Suppression State
Error C2678 binary '<': no operator found which takes a left-hand operand of type 'const _Ty' (or there is no acceptable conversion) C++_project32 c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xstddef 141
是我做错了什么,如果是,那到底是什么?我希望如果您发现一些不好的做法,也可以添加它:] 谢谢!
编辑#1: 我上传了完整的代码,并按建议在运算符<上添加了重载。 好像我必须提供此输出窗口:
1>------ Build started: Project: C++_Stelio_Kursova, Configuration: Debug Win32 ------
1>Source.cpp
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xstddef(141): error C2678: binary '<': no operator found which takes a left-hand operand of type 'const _Ty' (or there is no acceptable conversion)
1> with
1> [
1> _Ty=CTurist
1> ]
1>c:\users\echo\source\repos\c++_stelio_kursova\c++_stelio_kursova\source.cpp(24): note: could be 'bool CTurist::operator <(CTurist &)'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\system_error(319): note: or 'bool std::operator <(const std::error_condition &,const std::error_condition &) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\system_error(312): note: or 'bool std::operator <(const std::error_code &,const std::error_code &) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xstddef(141): note: while trying to match the argument list '(const _Ty, const _Ty)'
1> with
1> [
1> _Ty=CTurist
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xstddef(140): note: while compiling class template member function 'bool std::less<_Kty>::operator ()(const _Ty &,const _Ty &) const'
1> with
1> [
1> _Kty=CTurist,
1> _Ty=CTurist
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xutility(1110): note: see reference to function template instantiation 'bool std::less<_Kty>::operator ()(const _Ty &,const _Ty &) const' being compiled
1> with
1> [
1> _Kty=CTurist,
1> _Ty=CTurist
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xutility(264): note: see reference to class template instantiation 'std::less<_Kty>' being compiled
1> with
1> [
1> _Kty=CTurist
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xutility(264): note: see reference to variable template 'const bool is_empty_v<std::less<CTurist> >' being compiled
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xtree(1032): note: see reference to class template instantiation 'std::_Tree_comp_alloc<_Traits>' being compiled
1> with
1> [
1> _Traits=std::_Tmap_traits<CTurist,unsigned int,std::less<CTurist>,std::allocator<std::pair<const CTurist,unsigned int>>,false>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\map(82): note: see reference to class template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>' being compiled
1> with
1> [
1> _Kty=CTurist,
1> _Ty=unsigned int,
1> _Pr=std::less<CTurist>,
1> _Alloc=std::allocator<std::pair<const CTurist,unsigned int>>
1> ]
1>c:\users\echo\source\repos\c++_stelio_kursova\c++_stelio_kursova\source.cpp(43): note: see reference to class template instantiation 'std::map<CTurist,unsigned int,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' being compiled
1> with
1> [
1> _Kty=CTurist,
1> _Ty=unsigned int
1> ]
1>Done building project "C++_Stelio_Kursova.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
答案 0 :(得分:1)
std::map
是一个有序容器,其顺序基于地图的键。对于存在的订单,必须为密钥类型定义一个operator<
。 (这只是一种简化,但目前已经足够了。)
您做错了什么是没有为operator<
定义CTurist
,但是当您将CTurist
用作地图键时隐式使用了它。
最明显的做法是使用std::unordered_map
之类的无序容器,但这有其自身的要求,或者为您的operator<
类定义CTurist
,大概是根据游客的姓名和年龄。
如何定义operator<
并不重要,例如,顺序是升序还是降序,订购时是否先考虑年龄或名字都没有关系,只要您operator<
为所有不相等的CTurist
实例定义一致的顺序。
良好实践
1)通过const引用传递字符串和其他大对象
2)在构造函数中更喜欢初始化而不是赋值
所以
CHotel(const string& n, int r, int bc) :
name(n), rating(r), bedsCount(bc)
{
}
但总体上还不错。