关于 ofstream 的歧义的警告,但对于 ostream 则不然。有什么区别?

发布于 2024-12-21 17:47:34 字数 1407 浏览 0 评论 0原文

这并不重要。但我很好奇这个警告什么时候出现。我真正的问题是为什么 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╭ゆ眷念 2024-12-28 17:47:34

当您调用时,

os << t.y;

您有 2 个候选者:

ostream& operator << (ostream&, int) //1

并且

ofstream& operator << (ofstream&, Test) //2

没有这样的候选者

ofstream& operator << (ofstream&, int) //3

根据重载决策规则,1 和 2 都不适合您的调用。因此发出警告。对于ostream,1 显然是更好的匹配,因为两个参数完全匹配。

最好的解决方案是使用 std::ostream。为什么需要专门针对文件流进行重载。如果您需要将其流式传输到字符串中怎么办?重载 std::ostream 的输出流运算符(甚至是 std::basic_ostream 的模板化版本),并让编译器处理其余的事情。

When you call

os << t.y;

you have 2 candidates:

ostream& operator << (ostream&, int) //1

and

ofstream& operator << (ofstream&, Test) //2

There is no such candidate as

ofstream& operator << (ofstream&, int) //3

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 for std::ostream (or even a templatized version of std::basic_ostream) and let the compiler handle the rest.

红尘作伴 2024-12-28 17:47:34

正如警告告诉您的那样,对于 ofstream ,两种解释都需要转换:

  1. ofstream& -> static_cast(os) << 中的 ostream& ty,

  2. int ->在 os << 中测试 static_cast<测试>(ty)

如果直接使用 ostream&,则 int 解释需要转换,因此是首选。

As the warning tells you, with ofstream both interpretations require conversions:

  1. ofstream& -> ostream& in static_cast<ostream&>(os) << t.y,

  2. int -> Test in os << static_cast<Test>(t.y)

If you use ostream& directly, then the int-interpretation requires no conversion and hence is preferred.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文