类型衰减——它是什么以及为什么会出现?

2024-04-25

我很惊讶类型衰减在 SO 或其他地方没有得到很好的解释,也许我没有使用正确的术语进行搜索,或者也许我没有正确理解整个事情。我的问题是:它是什么,它是如何(为什么)到达那里的,它的规则是什么?


如果你想知道我为什么问,下面是我的哭泣型腐烂故事(not不过,问题的主题):

我最近正在努力处理一些简单的模板,我想做这样的事情:

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;
    }
};

这一切都很好,有一个模板函数需要一个函数对象,还有一个函数对象。该函数被设计为不返回函数对象的状态(就像类似的函数经常做的那样;它返回一些复杂计算的结果),所以我想我应该将它专门用于参考到对象。但类型衰减会妨碍(或者至少这是我的理解):

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 lost

DoStuff(static_cast<MyFunObj&>(fob)); // again, hampered by type decay

我知道如何解决这个问题,所以请不要回复如何解决。我只对类型衰减感兴趣,这只是作为我的问题的动机/说明性示例。如果你愿意,你可以发表一些对我使用的仇恨mutable.


我真的不认为你的问题显示了类型衰减的例子。术语“衰减”通常用于指代标准函数到指针、数组到指针以及左值到右值的转换。您所遇到的是模板参数推导的规则。

问题是模板参数推导基于types, not on 值类别。的类型ref在你的例子中是MyFunObj,这是一个lvalue那种类型的(顺便说一句,同样适用于fob)。由于演绎适用于类型,FunObj被推导为type of ref,这确实是MyFunObj.

在 C++11 之前,无法推导引用类型。 C++11 通过“转发引用”改变了这一点。这些引入了一种特殊情况,其中传递类型的左值U到声明为的函数参数T&& (where T是函数模板的模板参数)使用U&作为扣除类型而不是U。但这是一个特殊的规则,一个例外。通常,值类别在类型推导中不起任何作用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类型衰减——它是什么以及为什么会出现? 的相关文章

随机推荐