【发布时间】:2017-05-13 14:37:57
【问题描述】:
大多数IO stream manipulators 是具有以下签名的常规函数:
std::ios_base& func( std::ios_base& str );
但是,一些操纵器(包括最常用的操纵器 - std::endl 和 std::flush)是以下形式的模板:
template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& func(std::basic_ostream<CharT, Traits>& os);
那么,在下面的例子失败的情况下,std::cout << std::endl; 的编译如何成功:
$ cat main.cpp
#include <iostream>
int main()
{
auto myendl = std::endl;
std::cout << myendl;
}
$ g++ -std=c++11 main.cpp -o main
main.cpp: In function ‘int main()’:
main.cpp:5:24: error: unable to deduce ‘auto’ from ‘std::endl’
auto myendl = std::endl;
^
很明显,上下文(在std::cout << std::endl; 中)有助于编译器消除对std::endl 的引用的歧义。但是管理该程序的规则是什么?重载决议看起来像是一个真正的挑战,它必须同时回答两个问题:
-
std::endl<CharT, Traits>()是指std::endl的哪个专业化? -
operator<<指的是哪个函数?
模板参数推导 (1) 应该在重载决议 (2) 之前发生,但似乎需要执行 (2) 的(至少一部分)才能使 (1) 成功。
有些相关但绝不重复的问题是:
- Does std::endl work with both cout and wcout?
- Why does endl(std::cout) compile
- How does std::flush work?
这些问题和对它们的答案都没有解决模板参数推导的工作原理,该推导应该在重载解决之前但必须得到后者的帮助。
后续问题: How does overload resolution work when an argument is an overloaded function?
【问题讨论】:
-
@πάνταῥεῖ 这个问题不是重复的。 Dietmar Kühl 的回答甚至没有包含我在非常不同的问题中要求的信息(它只声明“编译器自动推断模板参数”,而我很好奇该推断是如何工作的)。
-
@Leon 您能否在您的问题中提出您的论点,为什么您认为在 Dietmar 或其他答案中没有明确解释?我可能会考虑重新提出您的问题。
-
@πάνταῥεῖ 我已经在我的编辑中添加了这些论点(在问题结束之前)。
-
好吧,询问时以minimal reproducible example 开头。
标签: c++ templates overload-resolution iomanip