无法重载 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
.
背景:
我正在阅读 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
.