Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将常量引用绑定到右值引用_C++_Rvalue Reference - Fatal编程技术网

C++ 将常量引用绑定到右值引用

C++ 将常量引用绑定到右值引用,c++,rvalue-reference,C++,Rvalue Reference,我在下面有一个私有成员函数(类模板的一部分,Heap): 现在,VS警告我,我正在返回的函数parent\u中的局部变量或临时(rvalue)的地址,这在最后是有意义的,因为当控件存在时/从的parent\u返回所有局部变量,包括函数参数 现在,当将的函数parent_更改为按值返回(而不是按常量ref)时,一切都开始工作了 我来自C++98(因此所有的右值引用对我来说都不清楚),问题是: 何时以及如何使用右值引用(&&&)来克服此问题?我是否可以引用(包括更改其值)编译器分配的这个临时对象并返

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

现在,VS警告我,我正在返回的函数
parent\u中的局部变量或临时(rvalue)的地址,这在最后是有意义的,因为当控件存在时/从
parent\u返回所有局部变量,包括函数参数

现在,当将
的函数
parent_更改为按值返回(而不是按常量ref)时,一切都开始工作了

我来自C++98(因此所有的右值引用对我来说都不清楚),问题是:
何时以及如何使用右值引用(
&&&
)来克服此问题?我是否可以引用(包括更改其值)编译器分配的这个临时对象并返回对它的引用(用作返回值)?

如果要根据返回表达式的值类别保留返回值的生存期语义,则不能返回
常量&
,甚至是
&&
,因为您将面临悬空引用的问题

相反,您可以对返回类型使用
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);
}
模板
decltype(auto)Heap::优先级(常量大小和索引)常量
{
decltype(auto)result=vec.at(index).second;
返回decltype(result)(result);
}
现在,返回类型将推断出正确的值类别,即l值引用的l值,pr值(临时值)的r值,以及x值(过期值)

return语句中的cast to
decltype(result)
用于根据id expression
result
命名的实体类型将表达式转换为适当的类型

您需要对调用堆栈中要保留生存期语义的所有函数使用此技术

您可以将此技术视为完美的转发,但方向相反,即在调用堆栈上,而不是向下


此答案基于本节中描述的技术。

如果您希望根据返回表达式的值类别保留返回值的生存期语义,则不能返回
常量&
,甚至不能返回
&
,因为您将面临悬空引用的问题

相反,您可以对返回类型使用
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);
}
模板
decltype(auto)Heap::优先级(常量大小和索引)常量
{
decltype(auto)result=vec.at(index).second;
返回decltype(result)(result);
}
现在,返回类型将推断出正确的值类别,即l值引用的l值,pr值(临时值)的r值,以及x值(过期值)

return语句中的cast to
decltype(result)
用于根据id expression
result
命名的实体类型将表达式转换为适当的类型

您需要对调用堆栈中要保留生存期语义的所有函数使用此技术

您可以将此技术视为完美的转发,但方向相反,即在调用堆栈上,而不是向下


这个答案基于本节中描述的技术。

规则是:从不,从不,从不,通过引用(任何类型的引用)返回函数本地对象。该对象将在函数结束时被销毁,留下一个悬空引用,并使用未定义的行为。通常对您有利-这意味着,如果您构建了大型本地对象,并且所有分支都导致返回该对象,则不会进行复制。它将直接在接收者的“内存”中创建。@aðam多亏了保证的复制省略和NRVO,这通常不是问题。@aðam@aðam如果你有一个复制成本很高的大结构,请为它提供移动语义。搬家应该便宜。(并且,正如其他人指出的,由于NRVO的原因,不会应用任何复制/移动。)规则是:从不,从不,从不,通过引用(任何类型的引用)返回函数本地对象。该对象将在函数结束时被销毁,留下一个悬空引用,并使用未定义的行为。通常对您有利-这意味着,如果您构建了大型本地对象,并且所有分支都导致返回该对象,则不会进行复制。它将直接在接收者的“内存”中创建。@aðam多亏了保证的复制省略和NRVO,这通常不是问题。@aðam@aðam如果你有一个复制成本很高的大结构,请为它提供移动语义。搬家应该便宜。(而且,正如其他人所指出的,由于NRVO,无论如何都不会应用复制/移动。)
template <typename Task, typename Priority>
const Priority& Heap<Task, Priority>::priority_of(const size_t& index) const
{
    return vec.at(index).second;
}
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);
}