std::left和std::right是C++中的输入/输出操作符,它们是如何工作的,以及为什么要以这种方式使用它们呢?

8

我正在学习C++,我的目标是在控制台中展示一个美观的表格。我尝试使用std::leftstd::right这些输入/输出操纵符,但现在当我看着我的代码时,我无法弄清楚这些东西到底是什么,以及它们使用了什么样的机制。

到目前为止,每个函数调用都要求我至少在函数名后面放上空括号(),这样就不会混淆哪些是函数,哪些不是。

cplusplus.comcppreference.com让我理解leftright确实是函数,但可以不使用括号来调用它们。

简而言之,为什么我可以像这样无需括号地随处放置left,而其他任何函数调用都要求我使用括号()

另外,cplusplus.com上说left是一种叫做"manipulator"的东西,但这是我第一次听到这样的说法。我不知道"manipulator"这个术语的定义是什么,也不知道网站上的内容是否有任何意义。

1
你的代码不调用操纵符,而是输入/输出运算符来完成。这有点复杂 :-) 在这里查看运算符18-20 链接。它们调用函数。 - BoP
2
请查看https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt上关于模板类`std::basic_ostream`支持的名为`operator<<()的成员函数的信息(std::ostream和一堆其他输出流类型都是std::basic_ostream的特化版本)。有很多重载,但其中三个(链接中的18到20号)是函数。每个重载都调用传递给它们的函数,并用于实现IO操作符。其中一个重载将接受left`,调用传递的函数,该函数将执行所需的操作。 - Peter
1
在cplusplus.com上确实提到了left是一种叫做"manipulator"的东西,但这是我第一次听说这样的说法,我不知道"manipulator"这个术语的定义,也不知道网站上的任何内容是否有任何意义。是时候进行研究了... - Jesper Juhl
1个回答

13

std::leftstd::right I/O 操纵符1) 用于设置 I/O 流中字段的对齐方式。要查看效果,还需要使用 std::setw 设置字段宽度。例如:

#include <iostream>
#include <iomanip>

int main() {
    std::cout << std::left  << '{' << std::setw(10) << "left" << "}\n"
              << std::right << '{' << std::setw(10) << "right" << '}';
}

这将输出:

{left      }
{     right}

I/O操作符是函数,可以使用()调用,但通常通过重载的<<操作符来调用,该操作符将这些操作符作为函数指针传递:
// func is a pointer to a function which accepts a reference
// to std.:ios_base, and returns a reference to std::ios_base
basic_ostream& operator<<(std::ios_base& (*func)(std::ios_base&)); // (18)

// I/O manipulators are functions:
//   std::ios_base& left( std::ios_base& str );

std::cout << std::left中实际发生的是什么?
std::cout.operator<<(&std::left);
// equivalent to
std::left(std::cout);

1) I/O操作符是位于<iomanip>头文件中的函数。

1
@ilkkachu 是的,那将是相等的;我也更新了答案 - Jan Schultke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接