问题标签 [temporary-objects]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1526 浏览

c++ - 以临时对象为参数的 C++ 对象构造函数

我写了一些代码,突然想到我正在做的事情可能是一个非常糟糕的主意。这是一个抽象的例子。关键是向量的引用传递。

所以我写了一些代码来表示 a class vector,其中包含 3D 向量的东西,还写了一个粒子类,它的位置向量可以用构造函数和向量实例初始化。

在我的main()函数中,我使用了一个临时对象来初始化粒子对象,如下所示:

这里可以看到创建了一个临时的vector实例,我假设它是放在栈的某个地方,然后调用了particle的构造函数。

这可以吗,或者它是一个非常糟糕的代码的例子?我怀疑后者,因为我是通过引用传递的,因此临时向量的实例可能无效?

希望有人可以澄清这一点?

0 投票
3 回答
185 浏览

c++ - 值返回的对象在哪里分配

问题是:按值返回时,临时对象分配在哪里?即,在堆栈上,在动态分配的内存中——在这种情况下编译器会做什么?

如More C++ Idioms/Move Constructor中所述,我正在深入研究 C++03 中移动构造函数习语中的底层逻辑,有趣的部分是如何返回对象:

return ret;和之间的点a(func)显然包含堆栈清理和进一步的复制构造,但是临时对象在传递到复制构造函数之前存储在哪里?也许,我在搜索结果中监督了答案,但仍然找不到解释。

编辑:

好的,这个例子可能看起来过于简单了。在实际应用中,我们可以这样写:

这样的类不是 POD,编译器很可能不会Command a(someInstanceOfOtherClass.getCommand("foo"));通过简单地在堆栈上分配值来优化复制构造。至少,涉及到 QString、QDateTime 和 TParamList 的复制构造。

如果我理解正确,getCommand()__thiscall调用约定,它要求被调用者自己清理堆栈。逻辑解决方案是将结果分配到内存中并返回一个指针。我将尝试不同的场景并查看组装情况。

0 投票
1 回答
950 浏览

c++ - 通过 const 引用临时延长寿命

0 投票
2 回答
123 浏览

c++ - 为什么最简单的C++代码编译不出来?

我的编译器是 VC++ 2013 RC。

由于错误 C2040,无法编译最简单的代码。

错误 C2040:“narrow_str”:“MyString”与“char *”的间接级别不同

为什么?

0 投票
2 回答
1330 浏览

sql-server-2012 - 无法绑定多部分标识符“字段”

我正在尝试使用存储在临时结果集中的数据(代码中的 SOURCE)用 SQL Server 2012 填充另一个表。执行以下代码时,我收到错误“多部分标识符“SOURCE.JnlDetoaId”不能约束”。

我在这里阅读了一些主题,但没有看到如何将它们应用于我的案例。请问有什么帮助吗?

0 投票
2 回答
1624 浏览

c++ - 为什么非 const 引用参数可以绑定到临时对象?

错误 C2664:“void f4(char &)”:无法将参数 1 从“char”转换为“char &”

有人告诉我,在 C++ 中,非常量引用参数不能绑定到临时对象;在上面的代码中,f2(f1());按预期触发错误。

但是,为什么相同的规则不适用于代码行f4(f3());

PS:我的编译器是VC++ 2013。即使我注释了这一行f2(f1());,包含的代码f4(f3());也会被编译,没有任何错误或警告。

更新:

MSDN说:

在以前的 Visual C++ 版本中,非常量引用可以绑定到临时对象。现在,临时对象只能绑定到 const 引用。

所以我认为这是VC++的一个错误。我已向VC++ 团队提交了错误报告

0 投票
1 回答
127 浏览

c++ - 为什么我们可以非常量引用临时对象并延长其生命周期?

正如我所知道的,非常量引用临时对象是不正确的。但是,上面的代码表明它在 C++ 中似乎是合法的。为什么?

我的编译器是 VC++ 2013。

0 投票
1 回答
246 浏览

c++ - 调用 vector.push_back() 时避免复制构造函数/析构函数

MemRef是一个包含指向内存的指针和长度的小对象。将关键部分中的字符串复制最小化是优化项目的核心。令牌是一个deque<MemRef>.

当我在输入缓冲区中识别标记时,我想构造MemRefs 并将它们添加到标记双端队列中。第一次尝试是:

因为我在这里看到了 dtor 调用,所以它告诉我foo正在被创建、复制,然后被销毁。下一次尝试是:

但我看到了同样的行为。我的猜测是正在创建一个临时对象,将其复制到双端队列中,然后将其销毁,这也许就是“移动语义”主题的来源(我对此非常不清楚)。

有没有办法,实际上,MemRef直接构建到令牌双端队列,而不创建和销毁临时?

(我使用 Apple LLVM 5.0 版(clang-500.2.79)和 --std=c++11)

0 投票
2 回答
509 浏览

c++ - 分配指向临时对象的指针——如何防止它?

我的类有一个具有以下原型的方法:

它从映射中检索一个值,将其转换为字符串,然后返回该字符串。

有人使用我的类如下:

除非我弄错了,否则这是将 buf 设置为指向临时字符串。不久之后,当他查看 *buf 时,它已损坏。

显然,我希望我的用户写:

作为 Block 的作者,我如何防止这样的滥用行为?或者有没有办法我可以以某种方式支持这种用法?

更新1:直到我更改了映射的实现,从直接保存值到保存“内存引用”——长度和指向缓冲区的指针,这个错误才被发现。但是get_field总是返回一个字符串——不是 astring*string&a——所以我假设它总是返回一个临时的。我不明白为什么它之前没有中断(我也很尴尬;我声称我的更改不会影响 API)。

我准备通知用户他必须修改他的代码,但我希望能够引用他违反的“规则”,并可能解释他之前是如何“走运”的。

更新 2:似乎有可能(参考更新 1),刚才出现错误的原因是我的“幕后”更改要求我将以下开关添加到 g++ 4.4.7:-std=gnu+ +0x,这可能影响了临时对象的回收方式。

0 投票
1 回答
90 浏览

c++ - 模板化操作符 string() 在临时对象时不会编译

有谁知道为什么 main 中的最后一行无法编译(注意是编译失败):

正如我对主要行的评论所指出的,

  • 从 Foo 到字符串的隐式转换在非临时对象(例如 foo)上编译得很好,
  • 以及转换为 int (或 long 等)时的临时对象
  • 通过方法转换为字符串时它确实工作正常
  • 以及如果类型const string&不是字符串

在VS2010上试过这个。请注意,上面的代码在 2005 年编译得很好,但我相信 2010 年是正确的。

如果我删除模板定义和特化并简单地明确定义每个重载,则通过运算符隐式转换为字符串可以正常工作:

我不想使用这种解决方法,因为它的可维护性较差。

有谁知道让 main() 的最后一行成功编译的另一种方法?我不认为对显式转换和模板化转换运算符的公认答案适用于此,因为无论是否涉及模板,都可能进行多种转换(char *、alloc、string),而且对象是临时对象的事实似乎很重要.

编辑:这篇文章中的原始代码显示了一些类内模板专业化,这是从我的原始源中为 SO 创建独立代码片段的人工制品(我将一些命名空间级专业化移动到类中,VS2010 没有抱怨)。问题在于专业化。我修改了发布的代码以更接近原始代码(就像我刚刚所做的那样),不使用课堂专业化(当然问题仍然存在)。Derek 的回答表明它可能特定于 VS2010。