我制作了自定义课程user
,并在另一个课程set<user> users
中制作了dbase
。我已成功重载类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>&&'
这是类operator<<
的{{1}}声明:
user
以下是完整的代码:(ideone)
ostream& operator<<(ostream &out, user &u) {
cout<<endl;
cout<<"Username: "<<u.uname;
cout<<endl;
return out;
}
答案 0 :(得分:3)
因此...
请发布完整的可编辑示例。在这种情况下,您没有为我们提供足够的信息来轻松调试您的代码。
对于您的特定问题,该代码可能如下所示:
#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;
}
请发布编译器报告的整个错误消息。在这种情况下,它实际上是:
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)
^
请注意,我没有以任何方式编辑错误消息。您可能会在邮件中提供其他信息,这些信息可能对试图回答您问题的人有所帮助。
而不是:
ostream& operator<< (ostream &out, user & user) { ... }
执行:
ostream& operator<< (ostream &out, user const & user) { ... }
当重载流exaction或流插入操作符时,您可能永远不会使用cout
或cerr
。相反,您已将流对象传递到您的函数中。在您的情况下,您已使用典型(预期)参数名称out
对其进行命名。
因此,您的两个流插入运算符应该将cout
的每个实例替换为out
。
这会使您的代码在扩展它时使用正确以使用诸如使用fstream将用户数据库写入文件,或者如果您想要将消息打印到{{1}也是。
请注意。这是一个问题,因为cerr
会返回对*it
的引用。因此,您现有的const User
重载并不匹配,因为它需要非const版本的用户。