推导L值参考类型



关于模板参数推导,特别是引用折叠和"通用引用",有很多讨论和澄清。这个问题涉及到相关的细节:如何自动推导类型?,Scott Meyers的这篇论文更为详细,可能会给出更多的例子和更广泛的背景:https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers,以及他的cppcon幻灯片:http://www.aristeia.com/TalkNotes/C++TypeDeductionandWhyYouCareCppCon2014.pdf。
我的问题涉及以下代码:

template <typename T> void f(T t) { t = 0; }
int main() {
int i{5};
int &ir{i};
f(ir);
cout << i << endl; // 5
f<decltype(ir)>(ir);
cout << i << endl; // 0
}

为什么我的模板函数f没有推导出它们的类型int &?根据Scott Meyers的幻灯片(幻灯片7(,ir是左值引用的事实被简单地忽略了。这完美地解释了这种行为,但为了完美地解释,我花了一些时间阅读参考文献和标准,试图找到它的内容,比如:

如果A是引用类型,则引用的类型将通过推导使用。

这是一个旧的离线版本的引用所说的(我通常使用(,尽管它是在标题转换函数模板下说的,我在标准中没有找到这个措辞。我发现的闭包我认为来自于重载模板的部分排序规则,但我不相信它会适用于这里,即使这是我想要的。


标准中是否有指定该行为的地方,或者我忽略的其他行为是否暗示了该行为?我真的很想告诉某人"因为这里的标准中有这些单词,所以不会推导出类型int &。">

C++中没有引用类型的表达式。变量ir的类型为int&,但表达式ir的类型为int。后一种类型用于类型推导,因为函数参数总是表达式(支持的init列表的特殊情况除外(。

参见[expr.type]/1

如果表达式最初的类型为"reference toT"([dcl.ref],[dcl.init.ref](,则在进行任何进一步分析之前,该类型将调整为T。表达式指定由引用表示的对象或函数,表达式是左值或x值,具体取决于表达式。

最新更新