无法重载 ofstream 运算符,因为 - 无法绑定到不相关类型的值(stroustrup c++​​ 第 10 章)

unable to overload ofstream operator due to - cannot bind to value of unrelated type (stroustrup c++ chapter 10)

背景:

我正在阅读 Stroustrup 的 c++ 书。我在第 10 章完成练习时遇到了一个问题。现在,据我所知,根据我看到其他人如何回答问题,我并没有严格遵循这本书。我想我只是对如何实现代码有了更多的了解。

我的总体目标是有一个写函数而不是在 main() 中。

以下函数的目的是return一个ofstream。

ofstream& c_data_file()
{
    string oname = "mydata.txt";
    ofstream ost {oname};
    if (!ost) {
        string error = "cannot open " + oname;
        throw runtime_error(error);
    }
    return ost;
}

此代码确实带有来自编译器的警告,我将其包括在内,因为它可能与问题有关。警告是:

Reference to stack memory associated with local variable 'ost' returned

ostream& operator<<(ostream& os, const Point& p)
{
    return os << "(" << p.x <<"," <<p.y <<")";
}

ofstream& operator<<(ofstream& ost, const Point& p)
{
    return ost << "(" << p.x <<"," <<p.y <<")";
}

ostream 工作正常(我在其他地方使用这个流)。 ofstream 不工作,returning 错误:

Non-const lvalue reference to type 'ofstream' (aka 'basic_ofstream') cannot bind to a value of unrelated type 'basic_ostream >'

以下是剩余的相关代码:

int main() {

    vector<Point> original_points;
 ofstream& ost = c_data_file();
    for (int i = 0; i<original_points.size(); i++) {
        ost << original_points[i] << "\n";
    }
    ost.close();
}

上网查了一整天,下面的问题好像是柜子里的:

overloaded operator << on ofstream concatenation problems

但是,我发现很难理解答案,而且据我所知,它并没有解决我的问题。

感谢您的阅读以及您能提供的任何帮助。

我在这里包括以下编辑以及我对 iksemyonov 的回复,希望能为大家清楚地表达问题。 Edit1:根据 TBBle 的建议解决了警告。主要问题仍然存在,如 link 所示,并且 iksemyonov 建议我应该使用 ostream 而不是 ofstream。这是有问题的。 Ostream(按照本书)用于将数据发送到 cout,这就是我正在做的事情(代码不存在)。我还想将相同的数据发送到一个文件(理想情况下如书中建议的那样通过 ofstream)。

编辑 2:遵循 link 和 iksemyonov 的建议行之有效。下面的一些评论帮助我执行了这些建议。所以感谢所有发表评论的人。

ofstream& c_data_file() 是 return 对不再存在的 ofstream ost; 的引用 (&)ofstream ost; 是本地对象,将被销毁一旦超出范围)

所以你可以做的是将你的函数修改为 ofstream c_data_file() 这样你将不再 return 一个临时对象。

您已经在您的函数中创建了一个本地 ofstream,因此您不能 return 引用它,因为它在您的函数结束后就消失了。

所以你必须 return 一个 ofstream 对象。

You can't copy streams,所以一定要走一走。幸运的是,在这种情况下这是自动的。 (假设是 C++11。如果不是,则需要重构代码)。

如果您在 gcc 5 之前使用 gcc,

所以对您的函数最简单的更改是:

ofstream c_data_file()
{
    string oname = "mydata.txt";
    ofstream ost {oname};
    if (!ost) {
        string error = "cannot open " + oname;
        throw runtime_error(error);
    }
    return ost;
}

来电者变成

ofstream ost = c_data_file();

根据OP提供的link,

overloaded operator << on ofstream concatenation problems

除了修复 returning reference to temporary 错误外,解决方法是更改​​

ofstream& operator<<(ofstream& ost, const Point& p)
{
    return ost << "(" << p.x <<"," <<p.y <<")";
}

ostream& operator<<(ostream& ost, const Point& p)
{
    return ost << "(" << p.x <<"," <<p.y <<")";
}

编译得很好。正如 link 中的答案所述,发生错误的原因是 ost << "(" return 是 ostream 类型的对象,并且进一步调用 operator<< 因此由于编译器报告的不兼容性而失败。

附带说明一下,不 return main 的退出代码不是一个好的风格,如 return 0.