运算符链在C++中是如何发生的
How does operator chaining happen in C++?
我这里有一个完全基本的C++问题。
#include <iostream>
using namespace std;
int main() {
int a = 255;
cout << hex << a << endl; // <-----
}
在上面的代码段中,std::cout
语句是如何链接的?
我知道 cout
的实现会返回对cout
对象的引用以允许发生链接,因此它应该执行为:
(((cout << hex) << a) << endl)
即等同于这些,按
-
cout << hex
-
cout << a
-
cout << endl
但情况并非如此,因为a
的值需要以某种方式转换为hex
形式!
编译器实际上如何链接运算符以实现转换?
你说得对,这正是它的工作原理。 hex
只有一个特殊类型,当传递给其operator<<
函数时,该类型会更改cout
对象的内部状态。然后,内部状态确定如何处理通过operator<<
传递给cout
的任何未来值。
std::hex
恰好是一个函数。 但是,cout << hex
不会这样调用十六进制函数:它将指向十六进制函数的指针传递给ostream
的operator<<
重载,该重载接受具有特定签名的函数指针。 然后通过该函数指针从运算符实现内部调用hex()
,并据我所知从那里修改ostream
对象。
通常如何实现hex
:
inline ios_base&
hex(ios_base& __base)
{
__base.setf(ios_base::hex, ios_base::basefield);
return __base;
}
如您所见,hex
本身不执行任何转换:相反,它在基本流中设置一个选项,以使用十六进制打印稍后传入的数字。
编辑(回复评论(
正如哈马尔正确指出的那样,难题的另一部分是如何称呼hex(ios_base& __base)
。具有以下签名的 <<
运算符重载:
ostream& operator <<(ostream& (*)(ostream&))
这种重载是流操纵器的基本实现细节。正是这种重载召唤了hex
,并让它发挥它的"魔力"(当然,这对你来说听起来不应该再像魔术了(。
std::hex
实际上在std::cout
对象中设置了一个标志,该标志将一直持续到重置IIRC。operator<<
本身从左到右计算,因此您的括号是正确的。
在我看来,十六进制只是一个包对象,对 cout 对象有副作用。在此之后,cout 将仅输出十六进制值。
std::hex 是一个更改 std::ostream 对象状态的函数。 http://www.cplusplus.com/reference/iostream/manipulators/hex/
- 为什么会发生堆损坏
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++中的赋值发生,尽管右侧出现异常
- 写入位置0x0000000C时发生访问冲突
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 函数何时会在c++中包含stack_Unwind_Resume调用
- C++取消引用指针.为什么会发生变化
- 为什么在读取文件大小时文件IO速度会发生变化
- Python中的for循环与C++有何不同
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 在cygwin中运行c++脚本时发生错误
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 当我们从/tp地址中添加/减去一个整数时会发生什么
- 编译器对数组声明大小的计算。什么时候发生?
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 当 I2C 值在C++中发生变化时收到通知
- 为什么:不同符号的整数比较只是偶尔发生?