操作符链接如何在C ++中发生?

时间:2012-03-04 14:12:54

标签: c++

我在这里有一个完全基本的C ++问题。

#include <iostream>
using namespace std;

int main() {
    int a = 255;
    cout << hex << a << endl; // <-----
}

在上面的代码中,std::cout语句是如何链接的?

我理解cout的实现将返回对cout对象的引用以允许链接发生,因此它应该执行为:

(((cout << hex) << a) << endl)

即。相当于这些,按顺序

  1. cout << hex
  2. cout << a
  3. cout << endl
  4. 但情况并非如此,因为a的某种价值需要转换为hex形式!

    编译器如何实际链接运算符以进行转换?

5 个答案:

答案 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/