重载自定义类集的提取操作符
Overloading extraction operator for a custom class set
我做了一个自定义类user
,并在另一个类dbase
中做了一个set<user> users
。我已经成功地重载了类user
的提取操作符,现在我正试图重载类dbase
的提取操作符。
这是我的代码:
ostream& operator<< (ostream &out, dbase &db) {
set<user>::iterator it;
for(it=db.users.begin(); it!=db.users.end(); it++)
out<<(*it)<<endl; //error reported on this line
return out;
}
但是我一直得到这个错误:
error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
这是user
类的operator<<
声明:
ostream& operator<<(ostream &out, user &u) {
cout<<endl;
cout<<"Username: "<<u.uname;
cout<<endl;
return out;
}
(ideone)
#include <iostream>
#include <set>
#include <string>
#include <sstream>
using namespace std;
template <class T>
string to_string(T x) {
stringstream ss;
ss<<x;
return ss.str();
}
class date {
int dd,mm,yyyy;
string str_date;
public:
string get_date() {
return to_string(dd)+"-"+to_string(mm)+"-"+to_string(yyyy);
}
friend ostream& operator << (ostream&,date&);
friend istream& operator >> (istream&,date&);
};
ostream& operator<< (ostream &out, date &d) {
out<<d.get_date();
return out;
}
istream& operator>> (istream &in, date &d) {
cin>>d.dd>>d.mm>>d.yyyy;
return in;
}
class user {
string uname, pwd;
string full_name, contact;
static unsigned long long int id;
date dob;
public:
bool operator < (const user &u) const {
if(uname.compare(u.uname)<0) return true;
return false;
}
void set_uname(string u) {
uname = u;
}
void set_attrib() {
string temp_pass;
while(1) {
cout<<"Full Name: ";
cin>>full_name;
cout<<"Password: ";
cin>>temp_pass;
cout<<"Confirm Password: ";
cin>>pwd;
if(pwd.compare(temp_pass))
cout<<"Passwords do not match. Try Again."<<endl;
else break;
}
cout<<"Contact Number: ";
cin>>contact;
cout<<"Date of Birth(dd mm yyyy): ";
cin>>dob;
}
friend ostream& operator<<(ostream&, user&);
};
ostream& operator<<(ostream &out, user &u) {
cout<<endl;
cout<<"Username: "<<u.uname;
cout<<endl;
return out;
}
class dbase {
set<user> users;
public:
void add_user() {
string uname;
user u;
while(1) {
cout<<"Username: ";
cin>>uname;
u.set_uname(uname);
if(users.find(u)==users.end()) {
u.set_uname(uname);
u.set_attrib();
users.insert(u);
break;
}
else
cout<<"Username already exists. Please try a different username."<<endl;
}
}
friend ostream& operator << (ostream&, dbase&);
};
ostream& operator<< (ostream &out, dbase &db) {
set<user>::iterator it;
user u;
for(it=db.users.begin(); it!=db.users.end(); it++)
out<<(*it)<<endl;
return out;
}
int main() {
return 0;
}
So…
<标题>第一课请张贴一个完整的可编译的例子。在这种情况下,你没有提供足够的信息让我们容易地调试你的代码。
对于您的特定问题,代码可能看起来像这样:
#include <iostream>
#include <set>
using namespace std;
class user {
public:
user(int id = 0): id(id) {}
int id;
};
class dbase {
public:
set<user> users;
};
bool operator<(user const & lhs, user const & rhs) {
return lhs.id < rhs.id;
}
ostream& operator<< (ostream &out, user & user) {
return out << "user(" << user.id << ")";
}
ostream& operator<< (ostream &out, dbase &db) {
set<user>::iterator it;
user u;
for(it=db.users.begin(); it!=db.users.end(); it++)
cout<<*it<<endl;
return out;
}
int main() {
dbase db;
db.users.emplace(3);
db.users.emplace(4);
cout << db << endl;
}
<标题>课2 h1> 发布编译器报告的整个错误消息。在本例中,它实际上是:
se.cc: In function ‘std::ostream& operator<<(std::ostream&, dbase&)’:
se.cc:28:16: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
cout<<*it<<endl;
^
In file included from /opt/gcc/4.8.1/include/c++/4.8.1/iostream:39:0,
from se.cc:1:
/opt/gcc/4.8.1/include/c++/4.8.1/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = user]’
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
注意,我没有以任何方式编辑错误消息。你可能遗漏了其他信息,而这些信息可能对试图回答你问题的人有帮助。
<标题> 3 课代替:
ostream& operator<< (ostream &out, user & user) { ... }
:
ostream& operator<< (ostream &out, user const & user) { ... }
<标题>课4 当重载流提取操作符或流插入操作符时,可能永远不应该使用cout
或cerr
。相反,您将一个流对象传递给函数。在您的示例中,您使用典型的(预期的)参数名称out
来命名它。
所以,你的两个流插入操作符应该将cout
的每个实例替换为out
。
这将使你的代码正确地工作,当你扩展它来使用诸如使用fstream将用户数据库写入文件,或者如果你想打印消息到cerr
。
提醒一下。这是一个问题,因为*it
返回对const User
的引用。所以你现有的operator<<
重载不匹配,因为它想要一个非const版本的User。
相关文章:
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么istream不支持右值提取
- 如何设置一个范围来提取我想要获得的信息
- 视觉工作室项目.提取源文件夹名称
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 从字符串中提取整数并形成一个数组
- C ++中的StringStream有助于使用向量从字符串中提取逗号分隔的整数,而不是空格分隔的整数,为什么?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 从 std::vector<无符号字符>切片中提取 int?
- Istream提取操作符:如何检测解析失败
- 重载自定义类集的提取操作符
- 使用文件提取操作符读取int或string
- 使用PoDoFo-lib从PDF操作符中的数组TJ中提取文本
- c++中重载流提取操作符
- 流插入/提取操作符重载函数的原型属于哪里?
- 类函数的c++提取操作符
- 如何在类中实现提取操作符
- c++流提取操作符重载
- c++中的流提取操作符