c – 静态与成员运算符重载:std :: operator <<和std :: ostream :: operator <<

前端之家收集整理的这篇文章主要介绍了c – 静态与成员运算符重载:std :: operator <<和std :: ostream :: operator <<前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
C的ostream类为运算符<<提供了许多默认重载,但它们并非都以相同的方式定义. char类型,字符串类型和rvalue流的 overloads定义为免费的命名空间范围函数,例如:
namespace std {
ostream &operator<<(ostream &os,char c);
}

而算术类型,streambuf和流操作符的overloads被定义为std :: ostream的成员函数,例如:

namespace std {
ostream &ostream::operator<<(int val);
}

我的问题

有这种区别的原因吗?我理解对这些运算符重载的调用操作稍有不同(即空闲命名空间范围定义的ADL),因此我认为出于优化目的,可能会优先考虑特定类型的运算符重载.但是这里std :: ostream对不同类型使用两种类型的定义.这允许的语义或实现优化是否有任何优势?

解决方法

I’d imagine there might be a preference to a particular type of operator overload for optimization purposes

好吧,不.在一天结束时,两者都作为函数调用执行.重载决策本身甚至没有明显的含义.由于标准规定在[over.match],第26段:

If either operand has a type that is a class or an enumeration,a
user-defined operator function might be declared that implements this
operator or a user-defined conversion can be necessary to convert the
operand to a type that is appropriate for a built-in operator. In this
case,overload resolution is used to determine which operator function
or built-in operator is to be invoked to implement the operator.

The set of candidate functions for overload resolution is the union of
the member candidates,the non-member candidates,and the built-in
candidates. The argument list contains all of the operands of the
operator. The best function from the set of candidate functions is
selected according to [over.match.viable] and [over.match.best].

所有这些运算符重载都一起解决.唯一的语义差异是从ostream派生的类可能会选择隐藏某些成员重载.这是根据派生类中的重载方式完成的.只有明确声明的重载才适用.与那些成员不同,自由函数重载将始终参与重载解析,即使对于从ostream派生的类也是如此.

由于派生类需要转换为ostream&为了选择自由函数重载,需要对其自己的隐式转换序列进行排序.如果所有重载都是自由函数,则可能会导致歧义.

因此,考虑很可能是将可能导致歧义(指针和算术类型)的类型与我们可能总是希望可用的有用类型(指向C字符串和单个字符的指针)分开.并允许隐藏“不太有用”的那些,以避免这些含糊不清.

正如W.F.所指出的那样. ostream实际上是basic_ostream< char>.自由函数恰好适用于仅需要流式传输的数据.流本地“字母”中的字符或字符串.所以对于basic_ostream< wchar_t>那些自由函数将接受wchar_t和wchar_t *.简单的流媒体很可能不需要访问流私有部分.

其他重载适用于在流式传输之前需要序列化的数据.由于所述序列化与流内部状态紧密耦合,因此使这些重载成为成员更有意义.

猜你在找的C&C++相关文章