为什么 ostream iomanip 在传递给 operator<< 时不需要模板参数?

Why does an ostream iomanip not need template parameters when passed to operator<<?

在 gnu stdc++ 头文件 ostream 的命名空间 std 中,这是 std::endl 的定义:

template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    endl(basic_ostream<_CharT, _Traits>& __os)
    { return flush(__os.put(__os.widen('\n'))); }

为什么可以在没有模板参数的情况下使用 endl 编写 std::cout << std::endl;

std::basic_ostream<CharT,Traits>::operator<< taking manipulators as function pointer. Template argument deduction 是在像 std::endl 这样的模板传递时执行的,因此不需要显式指定模板参数。

When possible, the compiler will deduce the missing template arguments from the function arguments. This occurs when a function call is attempted and when an address of a function template is taken.

This mechanism makes it possible to use template operators, since there is no syntax to specify template arguments for an operator other than by re-writing it as a function call expression.

#include <iostream>
int main() 
{
    std::cout << "Hello, world" << std::endl;
    // operator<< is looked up via ADL as std::operator<<,
    // then deduced to operator<<<char, std::char_traits<char>> both times
    // std::endl is deduced to &std::endl<char, std::char_traits<char>>
}

给定 std::cout << std::endl;,适当的 operator<< 的参数类型是 std::basic_ostream<char,std::char_traits<char>>& (*func)(std::basic_ostream<char,std::char_traits<char>>&),那么 std::endl 的模板参数将推导为 char 并且std::char_traits<char>.