问题描述
我正在研究自定义流类的可能设计。在现场和场外搜索了半个小时都没有找到我的问题的答案,所以我提出了一个新问题。
以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 (将#修改为@)