为什么 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
使用不同字符类型(char
、wchar_t
等)的输出流,即 std::cout
与 std::wcout
,等等
但是,您没有为模板参数提供任何值来告诉编译器您想使用 std::endl
的哪个特化,因此 auto
无法为它推断出具体类型,因此错误。
你将不得不做这样的事情:
auto& end = std::endl<char, std::char_traits<char>>;
在下面的代码中:
#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
使用不同字符类型(char
、wchar_t
等)的输出流,即 std::cout
与 std::wcout
,等等
但是,您没有为模板参数提供任何值来告诉编译器您想使用 std::endl
的哪个特化,因此 auto
无法为它推断出具体类型,因此错误。
你将不得不做这样的事情:
auto& end = std::endl<char, std::char_traits<char>>;