41

Consider the following snippet to test the upcoming C++17 feature decomposition declarations (formerly known as structured bindings)

#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);
}

This fails on both g++7-SVN and clang-4.0-SVN with the message:

decomposition declaration cannot be declared 'constexpr'

Dropping the constexpr definition and changing to a regular assert() works on both compilers.

None of the WG21 papers on this feature mention the constexpr keyword, neither in the positive nor the negative.

Question: why aren't decomposition declarations be allowed to be constexpr? (apart from "because the Standard says so").

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • 1
    "formerly known as structured bindings" ??? They are still called "structured bindings" now (http://eel.is/c++draft/dcl.struct.bind) Am I missing something historical? – L. F. Aug 09 '19 at 04:36

1 Answers1

42

Question: why aren't decomposition declarations be allowed to be constexpr? (apart from "because the Standard says so").

There is no other reason. The standard says in [dcl.dcl] p8:

The decl-specifier-seq shall contain only the type-specifier auto (7.1.7.4) and cv-qualifiers.

That means it can't be declared with constexpr.

This was the subject of a National Body comment on the C++17 CD, see US-95 in P0488R0:

Comment: There is no obvious reason why decomposition declarations cannot be declared as static, thread_local, or constexpr.
Proposed change: Allow constexpr, static, and thread_local to the permitted set of decl-specifiers.

Comments GB 16 and GB 17 are also related.

These comment were rejected for C++17 after review by the Evolution Working Group at the Nov 2016 meeting. It was unclear what some storage classes would mean on a structured binding declaration, and exactly how to change the specification to allow constexpr (simply allowing it in the grammar wouldn't say what it means). A paper exploring the design space was requested. It should be possible to change this in future without breaking any code, but there wasn't time to do it for C++17.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • 5
    OK, so `constexpr` support could be added in the upcoming Kona meeting? – TemplateRex Jan 12 '17 at 21:09
  • 1
    @TemplateRex: National Body comments are formal responses to ISO, and would need to be answered prior to the formal release. But the proposed change could well be rejected, e.g. if there was significant doubt about unintended side effects of that change. That said, if there is an _unobvious_ reason, that reason probably deserves a footnore. – MSalters Jan 13 '17 at 12:45
  • 2
    @MSalters thanks. I would be disappointed if this were not adopted. I would be one more thing to remember not to use when writing constexpr functions. – TemplateRex Jan 13 '17 at 13:28
  • I noticed that the current draft Standard still has the section that you quoted. Do you know what the reasoning was for rejecting comment US 95? – TemplateRex May 14 '17 at 20:00
  • 1
    @TemplateRex a new question about constexpr functions containing structured bindings: https://stackoverflow.com/questions/46253990/if-structured-binding-cannot-be-constexpr-why-can-they-be-used-in-constexpr-func – Ryan Haining Sep 16 '17 at 12:43
  • It seems that `static` and `thread_local` are allowed now. But `constexpr` is still not. – L. F. Aug 09 '19 at 04:35