gpt4 book ai didi

c++ - endl操纵器在哪里定义

转载 作者:太空狗 更新时间:2023-10-29 23:24:36 25 4
gpt4 key购买 nike

我们知道 endl 是操纵器,它在内部将 '\n' 放入缓冲区,然后刷新缓冲区。 endl 定义在哪里?什么是endl,它是宏还是函数还是变量还是类还是对象?如何定义自己的 endl 操纵器?

cout << "hello" << endl ; /*what is endl and  where it is defined */

最佳答案

std::endl是签名的函数模板:

template<class CharT, class Traits>
std::basic_ostream<CharT,Traits>& endl(std::basic_ostream<CharT,Traits>&);

std::basic_ostream::operator<<过载 std::basic_ostream<CharT,Traits>>::operator<<(std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&))接受某个签名的函数。

当你做 std::cout << std::endl , 重载解析在 std::endl 上完成,它确定了 std::endl 的正确模板类型并实例化一个函数。然后它会衰减为一个指针,并传递给 operator<< .

std::basic_ostream::operator<<然后在有问题的 ostream 上调用函数,并返回返回值。像这样的东西:

template<class CharT, class Traits>
std::basic_ostream<CharT, Traits>&
std::basic_ostream<CharT, Traits>::operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&)
) {
return func(*this);
}

但具体的实现取决于编译库作者1

std::endl导致打印换行符,然后告诉 ostream 刷新自身。你可以模拟做 std::cout << std::endl;通过这两行代码:

std::cout.put(std::cout.widen('\n'));
std::cout.flush();

究竟如何std::endl是否实现取决于编译器,但以上是您可能如何编写它的一个不错的近似值(自然地在通用流上)。

保证您可以访问 std::endl如果你#include <ostream> .如果您包含来自 std 的任何其他头文件,您可能可以访问它图书馆。什么文件准确定义它又取决于实现。

std::endl被称为“io 操纵器”。此技术旨在允许通过链接 << 将操作 io 流状态的函数设置为与输出命令“内联”一起打电话。

要创建您自己的,如果您希望它与单一类型的 ostream 一起工作,只需创建一个采用那种 ostream 的函数。通过引用,并通过引用返回它。它现在是一个 io 操纵器。

如果你想处理一组流,创建一个像这样的模板:

template<class CharT, class Traits>
std::basic_ostream<CharT, Traits>& bob(std::basic_ostream<CharT, Traits>& os)
{
return os << os.widen('b') << os.widen('o') << os.widen('b');
}

现在是一个输出 "bob" 的 io 操纵器.它可以对 basic_ostream 做任何你想做的事有问题。

另一种方案是这样的:

struct bob_t {
template<class OS>
OS& operator()(OS& os)const {
return os << os.widen('b') << os.widen('o') << os.widen('b');
}
template<class OS>
operator OS&(*)(OS&)() const {
return [](OS& os)->OS&{ return bob_t{}(os); };
}
};
static const bob_t bob;

哪里bob现在是一个可以用作 io 操纵器的对象。


1 这个<<重载是 A->(A->A)->A 类型的函数.基本上,我们不是将 X 传递给 f,而是将 X 和 f 传递给 <<。 ,然后执行 f(X) .纯语法糖。

事实std::endl是一个模板意味着完美转发由于这种技术它有点痛苦。我最终定义了无状态函数 endl_t类型,带有 operator basic_ostream<CharT,Traits>&(*)(basic_ostream<CharT,Traits>&)()const过载,所以有时我可以通过完美的转发代理传递过载集。

然后我们可以传递整个重载集 f:(A->A)<< ,并让“下一层”解决过载问题。

关于c++ - endl操纵器在哪里定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33553091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com