微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

流操纵器的免费函数与直接重载运算符<<

如何解决流操纵器的免费函数与直接重载运算符<<

我正在研究自定义流类的可能设计。在现场和场外搜索了半个小时都没有找到我的问题的答案,所以我提出了一个新问题。

std::endl为例。如果我没有记错的话,它被指定为大致像这样工作(认为这是“幻灯片代码”):

struct ostream
{
    using FManip = ostream& (*)(ostream&);
    ostream& operator<<(FManip f)
    {
        return f(*this);
    }
};

ostream& endl(ostream& s)
{
    /* ...do whatever... */
    return s;
}

https://godbolt.org/z/6MP5cseas

但是,我不清楚这样做的好处是什么,而不是拥有标记对象并直接为它们实现 operator<<

struct ostream
{
};

// (reserved name - use whatever convention fits when writing library code)
struct _EndlManipTag {};
static constexpr _EndlManipTag endl;

ostream& operator<<(ostream& s,_EndlManipTag tag)
{
    /* ...do whatever... */
    return s;
}

int main()
{
  ostream os;
  os << endl;
}

https://godbolt.org/z/dzj7v8fse

我知道第一个版本为额外的操纵器编写的代码略少。这不是最糟糕的原因,但它似乎更令人费解(有多少人知道 std::endl 实际上是一个函数),并且偏离了具有参数的操纵器的实现(例如 std::setw(n) 返回一个存储 n 并且存在适当的 operator<< 重载的对象 - 非常接近第二个片段)。

我想知道这里是否还有其他考虑因素(在标准化时或在查看当前 C++ 版本时)。也许重载决议的微妙之处?编译速度?易于优化?模板友好?错误信息?或者我在新代码中选择哪种方法根本无关紧要?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。