- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
直到现在,我一直假设临时对象在包含它的完整表达式 末尾被销毁。我最近遇到了规范的 [class.temporary]/5 部分,其中讨论了将临时对象分配给引用时发生的异常。大多数情况下,除了 [class.temporary]/5 中的一种特殊情况外,这似乎总是会延长临时变量的生命周期。 :
- A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
- A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
如果我正在读这篇文章,这表明如果构造函数引用它,则此类对象的生命周期可能比完整表达式短。
案例研究:
struct A
{
A(int);
~A();
};
struct B
{
B(const A& a)
: memberRef(a)
{ }
~B();
const A& memberRef;
};
// Just a few operators to use in my full expression
int operator+(const A&, const A&);
int operator+(const A&, const B&);
void testCase()
{
int case1 = A(1) + A(2);
int case2 = A(3) + B(A(4));
}
我为每个 A
构造函数提供了不同的参数,以便于引用创建为 A1、A2、< em>A3 和 BA4。
在 case1 中,A1 和 A2 以任意顺序构造,然后进行加法。 A1 和 A2 的生命周期受函数调用引用参数的规则约束。它们被扩展为包含加法运算符的完整表达式。
析构函数必须以相反的顺序调用,也在 [class.temporary]/5 中:
If the lifetime of two or more temporaries to which references are bound ends at the same point, these temporaries are destroyed at that point in the reverse order of the completion of their construction.
所以这告诉我必须在 A1、A2 或 A2、A1< 中调用这些对象的析构函数/em>,取决于编译器选择构造对象的顺序。到目前为止一切顺利。
对我来说麻烦的案例是case2。如果我没看错的话,因为 A4 绑定(bind)到传递给 B::B(const A&)
的引用,它的生命周期现在在该构造函数结束时结束,< strong>而不是表达式的结尾。
这向我暗示析构函数可以称为 A4、A3、BA4 或 A4、BA4,A3。但是,A4 的析构函数必须始终位于最前面,因为它出现在 BA4 的构造函数的末尾,而不是整个表达式的末尾。
这表明析构函数不可能按A3、BA4、A4的顺序调用,因为A4 的生命周期需要缩短。
我是否正确阅读了规范?如果是这样,这条规则的基本原理是什么?对我来说,让传递给构造函数的临时对象与传递给函数调用的临时对象一样长的时间似乎更自然,但看起来规范编写者努力制定了其他规则。
最佳答案
你在两者之间使用了错误的项目符号。
This one :
A temporary bound to a reference member in a constructor's ctor-initializer ([class.base.init]) persists until the constructor exits.
这里不适用。我们没有临时绑定(bind)到 ctor-initializer 中的引用成员。这种情况更像是:
struct B
{
B()
: memberRef(A(2)) // <==
{ }
~B();
const A& memberRef;
};
我们的情况正好是this one :
A temporary bound to a reference parameter in a function call ([expr.call]) persists until the completion of the full-expression containing the call.
我们有一个临时的 (A(4)
) 绑定(bind)到构造函数中的引用参数(构造函数调用仍然是函数调用,我们绑定(bind)的参数是 a
在 B(const A& a)
) 中,所以临时值一直存在到 full-expression 完成。
换句话说,您所展示的内容中没有悬空引用。所有这些关于将临时对象绑定(bind)到引用的规则都是关于生命周期扩展的。它们都不会缩短生命周期。
关于通过绑定(bind)到引用成员缩短了 C++ 临时变量的生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52433998/
我有一个 foo 类,它有一个 bar 方法,它接受可调用的东西(函数指针/仿函数)。这个可调用的东西应该作为绑定(bind)元素传递给另一个方法 doit 和第三个方法 bar_cb 方法。 #in
我正在尝试在我的 WPF 4.0 应用程序(使用 VS 2010 Pro RTM)中创建自定义 TabItem 模板/样式,但尽管一切似乎都正常工作,但我注意到跟踪窗口中存在绑定(bind)错误。 我
作为一名刚接触 Android 的开发人员,我想我可能误解了绑定(bind)服务。 我创建了一项服务来结束对服务器的访问。作为此服务的一部分,该服务正在监听多播地址,以识别本地网络上的设备何时出现和消
这个问题在这里已经有了答案: What is the use of the JavaScript 'bind' method? (23 个回答) 关闭 7 年前。 所以我一直在尝试了解一些 JS 上
我不明白这三种语法之间的区别: where a = f (b) do a <- f (b) do let a = f (b) 我确实明白了a <- f(b)与其他两个不同,在大多数情况下,我尝试了所有
我在将 Cocoa 项目从手动同步接口(interface)模型转换为绑定(bind)模型时遇到问题,这样我就不必担心接口(interface)粘合代码。 我关注了 CocoaDevCentral C
我正在尝试找出一种好的方法来对处理大数据集的代码进行并行化,然后将结果数据导入 RavenDb。 数据处理受 CPU 限制和数据库导入 IO 限制。 我正在寻找一种解决方案,以对 Environmen
我正在 foreach 循环中生成单选按钮。我试图将选中的属性绑定(bind)到父级中的基本可观察值。不幸的是,当单击单选按钮时,父级的属性似乎没有在单击处理程序中更新。 基于一些previous w
在我的 Windows Phone 应用程序中,我有两个 LongListSelectors并排在页面上。我想做到这一点,以便当用户滚动其中一个时,另一个滚动相同的量。 两个 LongListSele
我在网上看到这个问题准备面试: Given a non-preemptive kernel which type of process will get affected morein terms o
我有一个 foreach 绑定(bind),如下所示: Summary Permitting 原因是有两个选项卡始终存在,并且我根据是否添加了其他选项卡来添加其他选项
任何人都有绑定(bind)相同的情况DataContext到 TextBlock 中的 Text 属性(例如)。 我必须分配 DataContext以我的风格反射(reflect)基于 Datacon
给定以下代码: Login 和下面的javascript $(function () { $('#btnLogin').click(function () { co
我使用 boost::asio 创建了一个服务器。我在绑定(bind)到端点时遇到问题。所以,如果我在构造函数中初始化一个接受器: Server::Server(QWidget *parent) :
我正在将现有项目从 MySQL 转换为 Postgres。代码中有相当多的原始 SQL 文字使用 ? 作为占位符,例如 SELECT id FROM users WHERE
似乎在绑定(bind)某些数据时出错了,有人可以帮我解决我哪里出错了,尽管我无法弄清楚。 真的不需要在这里显示太多,这是 Binding,我已经通过移除背景并在其中放置颜色来测试背景,效果很好。 编辑
我正在尝试使用 wcf 构建一个 http 监听器(web 服务)。这个监听器是一个更大的桌面应用程序的一部分。此桌面应用程序还会调用 http 监听器。 当监听器接收到数据时,它应该被传递到桌面应用
嘿嘿。 我正在使用 Node.JS 和 child_process 来生成 bash 进程。我试图了解我是否正在执行 I/O 绑定(bind)、CPU 绑定(bind)或两者兼而有之。 我正在使用 p
尝试执行以下操作并出现“Got interpolation ({{}}) where expression was expected”错误。 {{item.name}} 谢谢!
我有一个导入的 Java 库,它是我解决方案中的“绑定(bind)库”项目。 我正在尝试从解决方案中的另一个项目绑定(bind)到第 3 方库中的服务。 第 3 方库文档 [在 java 中] 非常简
我是一名优秀的程序员,十分优秀!