【问题标题】:Scope of a variable initialized in the parameter list of a function在函数的参数列表中初始化的变量的范围
【发布时间】:2018-07-24 23:35:08
【问题描述】:

以下代码可以毫无问题地构建、编译和运行(C++、mingw)。但是,我是否保证在函数的参数列表中使用初始化列表构造的对象在该函数的范围内存在,即使该函数通过引用获取参数?

如果不是,那么在函数的参数列表(通过引用获取参数)中使用其初始化器列表创建对象时是否会很危险,因为它会立即被破坏:在这种情况下,函数不会没有副本,而是对内存的引用,它可能会或可能不会被另一个进程重新分配?

struct S
{
  S() : a(0), b(0) {}
  S(int a, int b) : a(a), b(b) {}
  int a;
  int b;
};

void foo(const S& s)
{
  std::cout << "s.a = " << s.a << std::endl;
  std::cout << "s.b = " << s.b << std::endl;
}

int main()
{
  foo({4,5}); // <-- What is the scope of the struct initialized here?

  return 0;
}

【问题讨论】:

  • 临时对象的作用域一直持续到完整表达式的末尾。在你的情况下,函数调用。这意味着您显示的代码是可以的。
  • 题外话:您应该考虑参数名称与成员名称不同的编码标准。
  • @ThomasMatthews:嗯,我喜欢这样。
  • 注意:这与将字符串文字传递给采用const std::string&amp; 的函数时出现的情况完全相同,因此如果它没有在那里工作那里有很多损坏的代码。
  • @MilesBudnek 嗯,这不是因为字符串文字永久存储在程序的静态内存位置中,直到 main 函数返回?

标签: c++ scope initializer-list


【解决方案1】:

这里prvalue具体化以从braced-init-list {4,5}创建S类型的临时对象,该对象在完整表达式的末尾被销毁。在你的情况下foo({4,5});

【讨论】:

    【解决方案2】:

    根据cppreference [lifetime]

    所有临时对象在评估的最后一步销毁 完整表达式,(词法上)包含它们所在的点 已创建,如果创建了多个临时对象,则它们是 破坏的顺序与创造的顺序相反。这是真实的 即使评估以抛出异常结束。

    这意味着临时对象将在函数返回后被销毁,因此非常安全。

    【讨论】:

      猜你喜欢
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多