关于 ofstream 的歧义的警告,但对于 ostream 则不然。有什么区别?
这并不重要。但我很好奇这个警告什么时候出现。我真正的问题是为什么 ostream 和 ofstream 受到不同的对待。
struct Test {
int y;
Test(int k) : y(k) {}
};
通过这个简单的结构,编译器可以将 int
转换为 Test
。
因此,我收到此代码的警告:
std :: ofstream& operator<< (std :: ofstream& os, const Test& t)
{
os << t.y;
return os;
}
当它看到 os << ty
它不知道我是否要推送名为 ty 的 int,或者是否要先将 int 转换为 Test 然后再推送它。这看起来很奇怪,你会认为它更喜欢非转换的 int 重载 ofstream&运算符<< (ofstream &os, int)
。
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3:
template_expl.cpp: In function ‘std::ofstream& operator<<(std::ofstream&, const Test&)’:
template_expl.cpp:15: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
/usr/include/c++/4.4/bits/ostream.tcc:105: note: candidate 1: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
template_expl.cpp:13: note: candidate 2: std::ofstream& operator<<(std::ofstream&, const Test&)
无论如何,解决此问题的一种方法是将 Test 中的构造函数标记为 explicit
。我可以忍受这一点。但奇怪的是,如果将 ofstream
替换为 ostream
,那么警告就会消失。知道为什么吗?
This is not important. But I'm curious as to when this warning appears. My real question is why ostream and ofstream are treated differently.
struct Test {
int y;
Test(int k) : y(k) {}
};
With this simple struct, the compiler sees that an int
can be converted to a Test
.
Therefore, I get a warning with this code:
std :: ofstream& operator<< (std :: ofstream& os, const Test& t)
{
os << t.y;
return os;
}
When it sees os << t.y
it doesn't know whether I want to push the int called t.y, or whether I want to convert the int to a Test first and then push it. This seems pretty weird, you'd think it'd prefer the non-converted int overload ofstream& operator<< (ofstream &os, int)
.
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3:
template_expl.cpp: In function ‘std::ofstream& operator<<(std::ofstream&, const Test&)’:
template_expl.cpp:15: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
/usr/include/c++/4.4/bits/ostream.tcc:105: note: candidate 1: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
template_expl.cpp:13: note: candidate 2: std::ofstream& operator<<(std::ofstream&, const Test&)
Anyway, one way to resolve this is to mark the constructor in Test as explicit
. I can live with that. But the weird thing is that if ofstream
is replaced with ostream
, then the warning goes away. Any idea why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您调用时,
您有 2 个候选者:
并且
没有这样的候选者
根据重载决策规则,1 和 2 都不适合您的调用。因此发出警告。对于
ostream
,1 显然是更好的匹配,因为两个参数完全匹配。最好的解决方案是使用 std::ostream。为什么需要专门针对文件流进行重载。如果您需要将其流式传输到字符串中怎么办?重载 std::ostream 的输出流运算符(甚至是 std::basic_ostream 的模板化版本),并让编译器处理其余的事情。
When you call
you have 2 candidates:
and
There is no such candidate as
According to the overload resolution rules, neither 1 nor 2 is better for your call. Hence the warning. In case of
ostream
, 1 is obviously a better match, because both arguments match exactly.The best solution is to go with
std::ostream
. Why would you need to overload specifically for file streams. What if you need to stream it into a string? Overload output stream operator forstd::ostream
(or even a templatized version ofstd::basic_ostream
) and let the compiler handle the rest.正如警告告诉您的那样,对于
ofstream
,两种解释都需要转换:ofstream& ->
,static_cast(os) << 中的 ostream&
tyint ->在
os << 中测试
static_cast<测试>(ty)如果直接使用
ostream&
,则int
解释需要无转换,因此是首选。As the warning tells you, with
ofstream
both interpretations require conversions:ofstream& -> ostream&
instatic_cast<ostream&>(os) << t.y
,int -> Test
inos << static_cast<Test>(t.y)
If you use
ostream&
directly, then theint
-interpretation requires no conversion and hence is preferred.