【问题标题】:Does Destruction of Arguments Occur Prior to Return?参数的销毁是否在返回之前发生?
【发布时间】:2016-06-05 10:39:43
【问题描述】:

好的,我有这个事件序列:

  1. 我构造了一个右值对象
  2. 我将一个迭代器作为参数传递给该 r 值对象到函数中
  3. 函数在这个迭代器上运行
  4. 函数按值返回此迭代器
  5. 我取消引用迭代器

我不知道是什么原因导致清除右值对象,是该行的终止吗?

好的,现在具体来说,我正在尝试为这个问题想出一个更好的答案:string Multiplication in C++ 我有代码:

const auto bar = 13U;
const char multiplicand[] = "0, ";
const auto length = strlen(multiplicand);
const string foo(&*generate_n(string(bar * length, '\0').begin(), bar * length, [&]() {
    static auto i = 0U;
    return multiplicand[i++ % length];
}) - bar * length);

所以我想知道在 generate_n 内部构造的 string 何时应该被销毁。 顺便说一下,这似乎在 gcc 5.1 上运行良好:http://ideone.com/Y8rDs5 但我可能只是不确定行为。 Visual Studio 2015 上的代码段错误这一事实暗示了这一点。

【问题讨论】:

  • this 不回答这个关于生命周期的问题吗?
  • @NathanOliver 确实如此,说:“通常这意味着它在;(或)forifwhileswitch 等)结束表示语句的结束。在你的例子中,它是函数调用的结束。”我认为) 是我问题的答案。但该声明中的“通常”并不是确定的。如果清理应该推迟到;,那么我很幸运,但这意味着微软做错了......
  • 我不知道这段代码是否调用了 UB,但它不是任何东西的更好答案。
  • @n.m.大声笑,也许:stackoverflow.com/q/35506712/2642059 可以从你的一些智慧中受益?如果我可以进行字符串乘法来初始化const string,我会非常兴奋,老实说,即使它很丑,我也会很兴奋。
  • 从函数中按值返回std::string。编译器知道如何优化它。

标签: c++ iterator arguments lifetime-scoping object-destruction


【解决方案1】:

string(bar * length, '\0') 等临时变量在 full 表达式的末尾被销毁。完整的表达式是const string foo 的初始化器。因此,在foo 的ctor 返回之前,临时字符串不会被销毁。

【讨论】:

  • 这也是我阅读第 12.2 节时的想法。但是,我们的意见不足以支持这个答案。能给个出处吗?
  • 来源确实是12.2。请注意,明显的例外不适用:“有两种上下文,其中临时对象在与完整表达式的结尾不同的点被销毁。第一个上下文是当 表达式作为初始值设定项出现时定义对象的声明符。在这种情况下,保存表达式结果的临时变量将持续存在,直到对象的初始化完成。这不适用,因为它仅适用于完整表达式中的临时对象,而不适用于任何其他临时对象。
  • 好的,我同意,但这是持有 return 的临时文件。 12.2[class.temporary]2 谈到表达式X b = f(X(2));:“一个实现可能使用一个临时对象来构造X(2),然后使用X 的复制构造函数将它传递给f();或者,X(2)可能会在用于保存论点的空间中构建。”我的问题是,如果参数不是按值传递,那么用于保存参数的临时/空间何时清理?
  • 6.6.3[stmt.return]3"返回实体的复制初始化在return语句的操作数建立的完整表达式末尾的临时对象销毁之前排序,反过来,在包含 return 语句的块的局部变量 (6.6) 的销毁之前对其进行排序。”这似乎表明在return 上,“完整表达式”已完成,但尚不清楚构造为参数的临时变量是否被视为“局部变量”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-24
  • 2013-10-03
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2018-11-27
  • 2021-12-24
相关资源
最近更新 更多