在 C++11 之前,没有办法推导出引用类型.C++11 通过转发引用"改变了这一点.这些引入了一种特殊情况,其中将 U 类型的左值传递给声明为 T&& 的函数参数(其中 T 是模板函数模板的参数)使用 U& 作为推导的类型而不是 U.但这是一个特殊的规则,一个例外.通常,值类别在类型推导中不起作用.I was surprised the type decay is not explained very well on SO or elsewhere, maybe I did not search using the correct terms or maybe I'm not understanding the whole thing correctly. My question is: what it is, how (why) did it get there and what are the rules of it?If you are wondering why I'm asking, below is my sob type decay story (not the subject of the question, though):I was recently struggling with some simple templates and I wanted to do something like this:template <class FunObj>double DoStuff(FunObj fob) // note that this returns double, not FunObj, as e.g. std::for_each() does{ /* ... */ }struct MyFunObj { mutable size_t num_invoked; // collect usage statistics MyFunObj() :num_invoked(0) {} bool operator ()(double some_arg) const { ++ num_invoked; return sin(some_arg) < .5; }};This is all nice, there is a template function expecting a function object, and a function object. The function was designed to not return the state of the function object (as similar functions often do; it was returning a result of some intricate computation instead), so I thought I would specialize it for a reference to the object. But the type decay gets in the way (or at least that is my understanding of it):MyFunObj fob;DoStuff(fob); // passed by value, usage statistics are lost (no surprise here)MyFunObj &ref = fob;DoStuff(ref); // MyFunObj& decays to MyFunObj, usage statistics are lostDoStuff(static_cast<MyFunObj&>(fob)); // again, hampered by type decayI know how to solve this, so please do not reply how. I'm only interested in type decay as such and this is here only as a motivation of my question / an illustrative example. If you like, you can post some hate for my use of mutable. 解决方案 I don't really think your question shows an example of type decay. The term "decay" is commonly used to refer to the standard function-to-pointer, array-to-pointer and lvalue-to-rvalue conversions. What you're hitting are the rules for template argument deduction.The thing is that template argument deduction is based on types, not on value categories. The type of ref in your example is MyFunObj, and it's an lvalue of that type (BTW, exactly the same holds for fob). Since deduction works on types, FunObj is deduced to the type of ref, which is indeed MyFunObj.Before C++11, there was no way to deduce a reference type. C++11 changed this with "forwarding references." These have introduced a special case where passing an lvalue of type U to a function parameter declared as T&& (where T is a template parameter of the function template) uses U& as the type for deduction instead of U. But that's a special rule, an exception. Normally, value categories don't play a role in type deduction. 这篇关于类型衰减 - 它是什么以及它为什么存在?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!