c++ - 将 const 引用绑定(bind)到右值引用

标签 c++ rvalue-reference

我在下面有这个私有(private)成员函数,(类模板的一部分,Heap):

template <typename Task, typename Priority>
const size_t& Heap<Task, Priority>::parent_of(const size_t& index) const
{
    // ** warning C4172: returning address of local variable or temporary
    return (this_index-1)/2;
}
我从其他函数调用它,如下所示:
template <typename Task, typename Priority>
void Heap<Task, Priority>::bubble_up(const size_t&   start_index)
{
    ....
    if (priority_of(start_index) > priority_of((parent_of(start_index)))) 
    { 
        ... do work ...
        //call recursively the bubble_up
        bubble_up(parent_of(start_index));
    }
    ...
}
问题是,priority_of函数参数 index在递归的第二次调用中损坏或释放:
template <typename Task, typename Priority>
const Priority& Heap<Task, Priority>::priority_of(const size_t& index) const
{
    return vec.at(index).second;
}
现在,VS 警告我,我在函数 parent_of 中返回局部变量或临时(右值)的地址,最后,这种行为是有意义的,因为当控制存在/从 parent_of 返回时包括函数参数在内的所有局部变量都已发布!
现在,当更改函数 parent_of按值返回(而不是通过 const ref),事情就开始了!
我来自 C++98,(所以我不清楚所有的右值引用)问题是:
我应该何时以及如何使用右值引用 (&&) 来克服这个问题?我可以引用(包括更改其值)编译器分配的这个临时对象并返回对它的引用(用作返回值)吗?

最佳答案

如果要根据返回表达式的值类别保留返回值的生命周期语义,则不能返回 const&。 ,甚至是 &&因为您将面临悬空引用的问题。
相反,您可以使用 decltype(auto)对于返回类型,以推断返回表达式的适当值类别:

template <typename Task, typename Priority>
decltype(auto) Heap<Task, Priority>::priority_of(const size_t& index) const
{
    decltype(auto) result = vec.at(index).second;
    return decltype(result)(result);
}
现在返回类型将推断出正确的值类别,即左值引用的左值,pr 值(临时)和 x 值(到期值)的 r 值。
类型转换 decltype(result)在 return 语句中用于根据 id-expression result 命名的实体的类型将表达式转换为适当的类型.
您需要对调用堆栈中要保留生命周期语义的所有函数使用此技术。
您可以将此技术视为完美转发,但方向相反,即向上调用堆栈,而不是向下。
这个答案基于这个有趣的 lightning talk 中描述的技术。 .

关于c++ - 将 const 引用绑定(bind)到右值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64787374/

相关文章:

c++ - 为什么需要在菱形层次结构的中间指定虚拟继承?

C++ "move from"容器

c++ - 将 C++ std::bind 替换为 lambda 的右值引用和可变模板

c++ - 为什么使用 std::forward<T> 而不是 static_cast<T&&>

java - 如何使用 NetBeans 包含的所有库依赖项构建可执行文件?

c# - 你如何在 C++ 中调用 C# 方法?

c++ - 错误 : class has no member named ‘show’

c++ - 射线与矩形的交点

c++ - 为什么 bitand 没有正确解析以形成右值引用?

c++ - Visual Studio 2013 中右值引用的初始化捕获