为什么引用不能捕获临时数据,而 const ref 和 rval ref 可以[重复]

2024-05-16

为什么引用不能捕获临时值,而const引用和右值引用可以捕获并延长对象生命。换句话说,虽然第一行是合法的,但第三行是不合法的:

const string &a = string("a");
string &&b = string("b");
string &c = string("c"); // why illegal?

引用自N1377 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm#Binding%20temporaries%20to%20references

Bjarne 在他的优秀著作《C++ 的设计与演化》中 讨论禁止将右值绑定到 第 3.7 节中的非常量引用。显示以下示例:

void incr(int& rr) {rr++;}

void g()
{
    double ss = 1;
    incr(ss);
}

ss 不会递增,因为必须创建一个临时 int 才能传递给 增量()。作者想说我们同意这一点 分析100%。霍华德早年甚至被这个“虫子”咬过一次 编译器。他花了很长时间才弄清楚发生了什么(在那 情况是从 float 到 double 的隐式转换创建了 临时的)。

这个基本原理(不将右值绑定到非常量(左值)引用)从 C++ 诞生之初一直持续到 C++11 (2011)。然而,同样的原理不适用于 const 的左值引用:

将临时对象绑定到 const 的左值引用是“安全”的,因为编译器会告诉您是否不小心对此临时对象进行了“无用”的修改。

那么为什么将右值绑定到右值引用是“安全”的呢?

再次引用自N1377 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm#Binding%20temporaries%20to%20references:

话虽如此,我们想补充一点:你永远不想绑定一个 临时到非常量引用......除非你这样做。

非常量引用并不总是作为“out”参数。 考虑:

template <class T>
class auto_ptr
{
public:
    auto_ptr(auto_ptr& a);
    ...
};

“复制”构造函数采用名为“a”的非常量引用。但是 修改“a”不是此函数的主要目标。这 主要目标是通过窃取“a”来构造一个新的 auto_ptr。如果一个” 碰巧引用了一个右值,这不是逻辑错误!

总之,有时您想要修改右值,有时则不想。不同类型的引用允许程序员告诉编译器它们处于哪种情况。

您问题中的绑定是 N1377 激发的绑定的逻辑结论。

移动语义提案确实致力于提出一个不需要更改语言的解决方案(即引入右值引用)。然而,仅库的解决方案并不令人满意,因为用于构建诸如移动构造函数之类的东西的语法过于复杂。

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

为什么引用不能捕获临时数据,而 const ref 和 rval ref 可以[重复] 的相关文章

  • 将可见性属性绑定到变量

    我有一个Border with Label里面一个Window
  • 在列标题上绘制矩形

    I m painting rectangle on the column headers in datagridview but on scrolling to right it disappears as in the picture s
  • C# - 带 GUI 的后台应用程序

    我的问题是我想创建一个后台应用程序 但具有可以恢复并最小化到系统托盘的用户界面 并且它从窗口启动 我尝试搜索如何启动 但只找到有关 Windows 服务的线程 没有 UI 或创建表单并隐藏它 所以我的问题是我应该如何开始 Windows 窗
  • Fortran DLL 导入

    Fortran 中有一段代码罗伯特 L 帕克和菲利普 B 斯塔克 http www stat berkeley edu 7Estark Code sbvq f FORTRAN subroutine bv key m n a b bl bu
  • 简单、高效的弱指针,当目标内存被释放时设置为 NULL

    有没有简单 高效的弱 保护指针 我需要多个指向同一对象的指针 当删除该对象时 这些指针都会自动设置为 NULL 有一个 主 指针始终用于删除对象 但可以有多个其他指针引用同一对象 以下是一些不太符合我的需求的解决方案 QPointer ht
  • 将多种类型存储为 C++ 字典中的值?

    我想编写一个行为几乎等同于 Python 字典的 C 对象 C 的std map and std unordered map容纳了 Python 字典已有的一些功能 但缺乏最重要的功能之一 即能够添加任意对象和类型 即使不可能 您离实现 P
  • 当 edmx 文件位于单独的项目中时出错

    我有问题说 在配置中找不到指定的命名连接 或者不打算与EntityClient提供者 或无效 我的 edmx 文件位于单独的项目中 但该项目的连接字符串app config 什么可能导致问题 确保 app config 位于设置为启动项目的
  • 通过 Microsoft Graph 从 Azure AD 获取组中的用户

    我正在通过 Microsoft Graph 从 AzureAD 请求用户列表 我取回了 User 对象 但它们的 MemberOf 属性始终为 null 我认为我可以使用 Expand 来专门请求该属性 虽然它不会导致错误 但它也不会填充该
  • 通过 WCF 提供类对象的数组或列表

    任何提供自定义类对象列表或数组的 WCF 客户端服务器示例都会对我有所帮助 但这是我到目前为止所得到的 这是我想提供的班级系统 namespace NEN Server FS Serializable public class XFS pr
  • 如何将多种语言设置放入单个 .clang-format 文件中

    我想为 java javascript 和 c 创建一个 clang 格式 我知道如何转储单一语言的示例配置 但不知道如何合并这 3 个配置文件 有关如何将多种语言配置放入单个文件中的示例 BasedOnStyle LLVM IndentW
  • WPF 通知获取属性的 PropertyChanged

    我有INotifyPropertyChanged实施使用CallerMemberName public event PropertyChangedEventHandler PropertyChanged protected virtual
  • 保存到会话状态的 DataTable 丢失事件处理程序

    我有一个来自强类型数据集的数据表 该数据集在 TableNewRow 事件上有一个事件处理程序 用于初始化一些日期字段 当我将此表保存到会话状态时 事件处理程序会正常触发 直到表被序列化 在后续请求中 当我从会话状态检索表时 事件处理程序不
  • 如何将值从控制器传递到asp.net中的视图?

    我正在开发一个应用程序 我需要将用户名的值从控制器传递到视图 我尝试了 ViewData 中给出的http msdn microsoft com en us library system web mvc viewdatadictionary
  • ElementReference 对 Blazor 中条件创建的元素的引用

    我正在尝试将焦点设置为有条件呈现的输入控件 我正在设置ElementReference但它的 id 和 context 都是空的
  • std::function 中参数的自动动态转换

    我们有多态类 A 和 B 例如 struct A virtual A struct B final public A void f std cout lt lt f lt lt std endl 我想分配一个变量std function
  • 如何在类中使用常量类变量声明常量数组?

    如何在类中使用常量类变量声明常量数组 是否可以 我不想要动态数组 我的意思是这样的 class test const int size int array size public test size 50 int main test t 5
  • 在 C++ 中的 Switch-Case 中执行 OR 运算

    你会如何在 C 中做到这一点 例如 如果用户按 ESC 或 q 或 Q 我试图触发程序退出 我尝试寻找它 但在 C 中没有找到它的语法 我知道如何使用 if else 来做到这一点 但是可以使用 switch case 来做到这一点吗 当然
  • 使用 DI 将参数传递给 DbContext

    我想向 DBContext 传递一个附加参数 如下所示 string myParam xx string con connenctionstring services AddDbContext
  • Outlook 插件:从选定的日历中获取元素

    我正在创建 Outlook 加载项 我想知道如何从选定的日历中获取元素 例如 我需要从名为 myCalendar 的日历中获取所有约会项目 现在 我可以从所有日历中获取所有约会项目 谢谢你 这些额外的日历作为主日历文件夹的子文件夹提供 所以
  • 为什么 Windows 只允许一个应用程序访问网络摄像头? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我一直在尝试用 C 制作一个示例网络摄像头应用程序 我发现该应用程序无法同时运行 Skype 或 Oovoo 或任何其他应用程序运行 反之亦然 为什么

随机推荐