【问题标题】:Address of array prvalue数组prvalue的地址
【发布时间】:2019-02-14 17:51:32
【问题描述】:

我不明白为什么这不起作用:

auto a = (int[]){1, 2, 3, 4, 5};

> error: taking address of temporary array

我知道数组左值在转换为右值时会衰减为指针,但这里的数组已经是右值(实际上是纯右值),因此不需要衰减。我本来希望a 被推导并初始化为int[5]。为什么要取临时地址?

【问题讨论】:

  • 我正在寻找答案,但是。 This 可能是相关的,因为 auto 无法做到这一点。
  • 这个语法是ill-formed。

标签: c++ arrays temporary-objects


【解决方案1】:

我本来希望 a 被推导并初始化为 int[5]

遗憾的是,这不是 C 数组的工作方式。数组衰减为指针。您不能真正拥有“数组值”。如果将 auto 替换为推导的类型,则如下所示:

int* a = (int[]){1, 2, 3, 4, 5};

衰变必须取地址做指针。

这很容易通过使用引用来解决,因为对临时对象的引用会延长它们的生命周期:

auto&& a = (int[]){1, 2, 3, 4, 5}; // works!

这是在 compiler explorer 上运行的示例。

当然,使用std::array 你会得到一个很好的语法和值语义:

auto a = std::array{1, 2, 3, 4, 5};

【讨论】:

  • auto a = (const int[]){1, 2, 3, 4, 5}; 也应该可以工作。
  • 嗨@Unimportant,我得到了与vs141相同的编译器错误,即使是常量。
  • @lakeweb 也许 vs141 不允许复合文字,严格来说,C++ 不支持。 gcc 允许它们(但在使用-pedantic 编译时会发出警告)。这是与问题中的存储问题不同的问题。
  • 我不明白你的争论链。 std::is_same_v<decltype((int[5]){1, 2, 3, 4, 5}), int[5]> 返回 true,std::is_same_v<decltype((int*){1, 2, 3, 4, 5}), int[5]> 返回 false,那么为什么 auto a = (int[]){1, 2, 3, 4, 5}; 应该与 int* a = (int[])(1, 2, 3, 4, 5); 相同?我在草稿中找不到找到你论文的那一行。由于int[5] 是一个聚合类型,至少auto a = (int[5]){1, 2, 3, 4, 5}; 应该可以工作......我的意思是auto aggregate = (A){1, 2, 3, 4, 5}; 也适用于每个具有5 个int 成员的聚合类型A。
  • 嗨 @Unimportant ,是的,这不是我第一次遇到 gcc 允许不使用 c++ 的东西,而且微软对此保持严格。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-01-14
  • 2015-09-29
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多