Endl机械手在哪里定义 [英] Where is endl manipulator defined

查看:71
本文介绍了Endl机械手在哪里定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We know that endl is manipulator and internally it put '\n' to buffer and then flush up the buffer. Where is endl defined? What is endl, is it macro or function or variable or class or object? How can I define my own endl manipulator?

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,特质&(* func)(std :: basic_ostream< CharT,特质&))接受具有特定签名的功能.

The std::basic_ostream::operator<< overload std::basic_ostream<CharT,Traits>>::operator<<(std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&)) accepts a function of a certain signature.

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

When you do std::cout << std::endl, overload resolution is done on std::endl, which determines the proper template types for std::endl and instantiates a function. This then decays into a pointer, and is passed to operator<<.

std :: basic_ostream :: operator<< 在有问题的ostream上调用该函数,并返回返回值.像这样:

std::basic_ostream::operator<< then calls the function on the ostream in question, and returns the return value. Something like:

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);
}

但是确切的实现取决于编译器库writer 1 .

But the exact implementation is up to the compiler library writer1.

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

std::endl causes a newline to be printed, and then tells the ostream to flush itself. You can emulate doing std::cout << std::endl; via these two lines of code:

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

std :: endl 的确切实现方式取决于编译器,但以上内容是如何编写(自然地在通用流上)的一个不错的近似值.

How exactly std::endl is implemented is up to the compiler, but the above is a decent approximation of how you might write it (naturally on a generic stream).

如果您 #include< ostream> ,则可以保证可以访问 std :: endl .如果包含 std 库中的任何其他头文件,则可以访问它.确切定义什么文件还是要取决于实现.

You are guaranteed to have access to std::endl if you #include <ostream>. You may have access to it if you include any other header file from the std library. What file exactly defines it is again up to the implementation.

std :: endl 被称为"io操作器".此技术旨在通过将<< 调用链接在一起,从而使用输出命令内联"设置操作io流状态的函数.

std::endl is known as an "io manipulator". This technique is intended to allow functions that manipulate the io stream's state to be set up "inline" with output commands by chaining << calls together.

要创建自己的代码,如果您希望它与单一类型的ostream一起使用,只需创建一个函数即可,该函数通过引用采用该 ostream 并通过引用将其返回.现在它是一个io机械手.

To create your own, if you want it to work with a single type of ostream, simply create a function that takes that kind of ostream by reference, and returns it by reference. It is now an io manipulator.

如果要处理一组流,请创建一个模板,如下所示:

If you want to handle a set of streams, create a template like:

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');
}

现在是io机械手,可以打印"bob" .它可以对有问题的 basic_ostream 做任何您想做的事情.

which is now an io manipulator that prints "bob". It can do whatever you want to the basic_ostream in question.

替代方案是这样:

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机械手的对象.

where bob is now an object that can be used as an io manipulator.

1 << 重载是 A->(A-> A)-> A .基本上,不是将X传递给f,而是将X和f传递给<< ,然后执行 f(X).纯语法糖.

1 This << overload is a function of type A->(A->A)->A. Basically, instead of passing X to f, we pass X and f to <<, which then does f(X). Pure syntactic sugar.

std :: endl 是模板的事实意味着,由于这种技术,完美转发它有点麻烦.我最终使用 operator basic_ostream< CharT,Traits&(*)(basic_ostream< CharT,Traits&&)()const()const 定义了无状态函数 endl_t 类型超载,因此有时我可以将超载集传递给完美的转发代理.

The fact that std::endl is a template means that perfect forwarding it is a bit of a pain due to this technique. I end up defining stateless function endl_t types, with an operator basic_ostream<CharT,Traits>&(*)(basic_ostream<CharT,Traits>&)()const overload, so I can pass the overload set through perfect forwarding proxies sometimes.

然后,我们可以将 f:(A-> A)的整个重载集合传递给<< ,并进行下一层向下"解析超载.

Then we can pass the entire overload set of f:(A->A) to <<, and have the "next layer down" resolve the overload.

这篇关于Endl机械手在哪里定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆