从`operator<<`

时间:2015-07-01 19:59:24

标签: c++ stream overloading

关于operator<<的所有指南都说您应该返回输出流:

ostream & operator<<(ostream &os, const Foo &x) { os<<"foo"; return os; }

但它不能只是更简单一点吗?

ostream & operator<<(ostream &os, const Foo &x) { return os<<"foo"; }

如果被调用<<跟随指南并返回其第一个参数,那么它应该是100%相同。但我依靠的是一些无法保证的东西吗?在某些情况下它会失败吗?

我为什么要这样?不只是为了保存击键(我们不在codegolf.SE) 实际使用情况有点复杂:

enum class Foo { A, B, C };
ostream & operator<<(ostream &os, const Foo &x) {
    switch (x) {
        case A: return os << "A";
        case B: return os << "B";
        case C: return os << "C";
    }
    return os << "Bad Foo (" << (int)x << ")";
}

与我发现的所有替代方案相比,多次返回使代码更简单,更易读(想象50个案例,而不是3个案例)。请注意,缺少default允许编译器警告缺少的情况,因此在添加枚举值时不会忘记添加一个。

2 个答案:

答案 0 :(得分:4)

假设您正在使用的超载正在返回引用,这些

ostream & operator<<(ostream &os, const Foo &x) { os<<"foo"; return os; }
ostream & operator<<(ostream &os, const Foo &x) { return os<<"foo"; }

将具有相同的效果并允许通常的链接

cout << Foo::A << Foo::B;

如果第一句话不成立(例如调用其他一些不返回对流对象的引用的自定义重载)那么你必须显式返回流引用或者如果你仍然提供不同的重载想把这些陈述联系起来。

答案 1 :(得分:1)

由于预期能够进行链接,因此如果违规类定义不遵循惯例,则您的简化应该有效,并且在编译时将失败

的任何地方
now.getMillis()

会起作用,你的简化也是如此,如果没有一个真正的保证人就足够了

具体而言,保证问题中字符串文字的now.toEpochMilli()能够返回正确的std::cout << a << b << std::endl;