为什么 std::endl 的类型推导失败?

Why does the type deduction for std::endl fails?

在下面的代码中:

#include <iostream>

auto& print = std::cout; // Type deduction for std::cout works
auto& end = std::endl;   // But the std::endl is exception here

int main(void) {
  print << "Hello" << end;

  return 0;
}

std::cout 的类型推导正确进行,但为什么它不适用于 std::endl

注意:删除对运算符(& 符号)的引用也不起作用。


VS 代码说:

并且编译器生成以下内容:

$ g++ -Wall -O3 -std=c++14 -o main main.cpp; ./main

main.cpp:4:18: error: unable to deduce 'auto&' from 'std::endl'
    4 | auto& end = std::endl;    // But the std::endl is exception here
      |                  ^~~~
main.cpp:4:18: note:   couldn't deduce template parameter 'auto'

std::cout 是一个具体类型 std::ostream 的对象(又名 std::basic_ostream<char> 特化),因此 auto 可以推断出它的类型。

std::endl 根本不是一个对象,它是一个模板函数(具体来说,一个以模板化的 std::basic_ostream 对象作为参数的流操纵器):

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

作为模板允许 std::endl 使用不同字符类型(charwchar_t 等)的输出流,即 std::coutstd::wcout,等等

但是,您没有为模板参数提供任何值来告诉编译器您想使用 std::endl 的哪个特化,因此 auto 无法为它推断出具体类型,因此错误。

你将不得不做这样的事情:

auto& end = std::endl<char, std::char_traits<char>>;

Live Demo