我在这里有一个完全基本的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
形式!
编译器如何实际链接运算符以进行转换?
答案 0 :(得分:22)
你说得对,这正是它的运作方式。 hex
只有一个特殊类型,可以在传递给cout
函数时更改operator<<
对象的内部状态。然后,内部状态将确定如何处理通过cout
传递给operator<<
的未来值。
std::hex
恰好是一个功能。 cout << hex
不会像这样调用十六进制函数:它将指向十六进制函数的指针传递给operator<<
的{{1}}重载,它接受具有特定签名的函数指针。然后通过该函数指针从运算符实现内部调用ostream
,并据我所知从那里修改hex()
对象。
答案 1 :(得分:8)
以下是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&))
此重载是stream manipulators的基本实现细节。正是这种重载调用了hex
,并让它发挥了它的“魔力”(当然这对你来说听起来不应该像魔术一样)。
答案 2 :(得分:2)
std::hex
实际上在std::cout
对象中设置了一个标志,该标志将一直持续到重置IIRC。 operator<<
本身是从左到右评估的,所以你的parens是正确的。
答案 3 :(得分:1)
从我的观点来看,hex只是一个包对象,它对cout对象有副作用。此cout之后只输出十六进制值。
答案 4 :(得分:1)
std :: hex是一个更改std :: ostream对象状态的函数。 http://www.cplusplus.com/reference/iostream/manipulators/hex/