std::left 和 std::right I/O 操纵器是如何工作的,为什么它们被使用?

How do the std::left and std::right I/O manipulators work, and why are they used in the way they are used?

提问人:Anton Shustikov 提问时间:8/15/2023 最后编辑:Jan SchultkeAnton Shustikov 更新时间:9/10/2023 访问量:692

问:

我正在学习C++,我的目标是在控制台中精美地显示一个表格。我尝试使用 和 I/O 操纵器,但现在我查看我的代码,我无法弄清楚这些东西到底是什么以及它们采用什么样的机制。std::leftstd::right

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

cplusplus.comcppreference.com 让我理解 和 确实是函数,但这些函数可以在不使用括号的情况下调用。leftright

简而言之,为什么我可以像这样放在没有括号的地方,但任何其他函数调用都需要我有括号?left()

此外,它在 cplusplus.com 上说这是一种叫做“操纵器”的东西,但这是我第一次听到这样的东西。我不知道“操纵者”一词的定义是什么,也不知道网站上的任何内容是否真的有任何意义。left

C++ IOstream iomanip

评论

1赞 BoP 8/15/2023
您的代码不会调用操纵器,而 I/O 运算符会调用。这很复杂:-)在这里查看运算符 18-20。他们调用函数。
2赞 Peter 8/15/2023
查看有关模板化类支持的成员函数的 en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt 信息(,以及一堆其他输出流类型是 )。有一堆重载,但其中三个(链接中的数字 18 到 20)是函数。这些重载中的每一个都调用传递给它们的函数,并用于实现 IO 操纵器。其中一个重载将接受 ,调用传递的函数,该函数将执行所需的操作。operator<<()std::basic_ostreamstd::ostreamstd::basic_ostreamleft

答:

13赞 Jan Schultke 8/15/2023 #1

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> 标头中的函数。