从"运算符<<返回"<<"的结果

Returning the result of `<<` from `operator<<`

本文关键字:lt 结果 返回 运算符      更新时间:2023-10-16

关于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允许编译器警告丢失的事例,因此在添加枚举值时不会忘记添加一个。

假设您使用的重载返回引用,则这些

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;

如果第一句话不成立(例如,调用其他自定义重载,该重载不返回对流对象的引用),那么如果您仍然想链接这些语句,则必须显式返回流引用或提供不同的重载。

由于它被期望能够链接,因此简化应该有效,并且如果有问题的类定义不遵循约定,则在编译时会失败

所在的任何地方

std::cout << a << b << std::endl;

如果没有真正的保证,简化就足够了

具体地说,在您的问题中,字符串文字的operator <<被保证返回正确的ostream