【问题标题】:Why can't decomposition declarations be constexpr?为什么分解声明不能是 constexpr?
【发布时间】:2017-01-12 21:01:02
【问题描述】:

考虑以下 sn-p 来测试即将推出的 C++17 功能分解声明(以前称为结构化绑定)

#include <cassert>
#include <utility>

constexpr auto divmod(int n, int d)
{
    return std::make_pair(n / d, n % d); // in g++7, also just std::pair{n/d, n%d}
}

int main()
{
    constexpr auto [q, r] = divmod(10, 3);
    static_assert(q == 3 && r ==1);
}

这在 g++7-SVN 和 clang-4.0-SVN 上都失败了,消息是:

分解声明不能声明为'constexpr'

删除constexpr 定义并更改为常规assert() 对两种编译器都有效。

关于此功能的 WG21 论文均未提及 constexpr 关键字,无论是正面的还是负面的。

问题:为什么不允许分解声明为constexpr? (除了“因为标准这么说”)。

【问题讨论】:

  • "以前称为结构化绑定" ???它们现在仍然被称为“结构化绑定” (eel.is/c++draft/dcl.struct.bind) 我错过了一些历史性的东西吗?

标签: c++ constexpr c++17 structured-bindings


【解决方案1】:

问题:为什么不允许分解声明为 constexpr? (除了“因为标准这么说”)。

没有其他原因。该标准在 [dcl.dcl] p8 中说:

decl-specifier-seq 应仅包含 type-specifier auto (7.1.7.4) 和 cv-qualifiers

这意味着它不能用constexpr 声明。

这是 C++17 CD 上 National Body 评论的主题,请参阅P0488R0 中的 US-95:

评论:没有明显的原因分解 声明不能声明为静态, thread_local 或 constexpr。
建议的更改: 允许 constexpr、static 和 thread_local 到 允许的 decl-specifiers 集。

注释 GB 16 和 GB 17 也是相关的。

进化工作组在 2016 年 11 月的会议上审查后,这些评论被拒绝用于 C++17。目前尚不清楚某些存储类在结构化绑定声明中意味着什么,以及如何更改规范以允许constexpr(仅在语法中允许它不会说明它的含义)。需要一份探索设计空间的论文。将来应该可以在不破坏任何代码的情况下更改它,但是对于 C++17 没有时间这样做。

【讨论】:

  • 好的,所以constexpr 支持可以在即将举行的 Kona 会议中添加?
  • @TemplateRex:National Body cmets 是对 ISO 的正式回应,需要在正式发布之前得到答复。但是提议的更改很可能会被拒绝,例如如果对该更改的意外副作用存在重大疑问。也就是说,如果有一个不明显的原因,那么这个原因可能值得一提。
  • @MSalters 谢谢。如果这不被采纳,我会很失望。在编写 constexpr 函数时要记住不要使用另一件事。
  • 我注意到当前的标准草案仍然有你引用的部分。你知道拒绝评论 US 95 的理由是什么吗?
  • @TemplateRex 关于包含结构化绑定的 constexpr 函数的新问题:stackoverflow.com/questions/46253990/…
猜你喜欢
  • 1970-01-01
  • 2016-12-15
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 2014-02-27
  • 2021-09-06
  • 2020-05-11
  • 1970-01-01
相关资源
最近更新 更多