重载自定义类集的提取运算符

时间:2014-08-11 14:50:37

标签: c++ stl set

我制作了自定义课程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;
}

1 个答案:

答案 0 :(得分:3)

因此...

第1课

请发布完整的可编辑示例。在这种情况下,您没有为我们提供足够的信息来轻松调试您的代码。

对于您的特定问题,该代码可能如下所示:

#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课

请发布编译器报告的整个错误消息。在这种情况下,它实际上是:

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课

当重载流exaction或流插入操作符时,您可能永远不会使用coutcerr。相反,您已将流对象传递到您的函数中。在您的情况下,您已使用典型(预期)参数名称out对其进行命名。

因此,您的两个流插入运算符应该将cout的每个实例替换为out

这会使您的代码在扩展它时使用正确以使用诸如使用fstream将用户数据库写入文件,或者如果您想要将消息打印到{{1}也是。

第5课

请注意。这是一个问题,因为cerr会返回对*it的引用。因此,您现有的const User重载并不匹配,因为它需要非const版本的用户。