This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2560. `is_constructible` underspecified when applied to a function type

Section: 21.3.5.4 [meta.unary.prop] Status: C++17 Submitter: Richard Smith Opened: 2015-11-14 Last modified: 2017-07-30

Priority: 0

View other active issues in [meta.unary.prop].

View all other issues in [meta.unary.prop].

View all issues with C++17 status.

Discussion:

What is `is_constructible<void()>::value`? Per 21.3.5.4 [meta.unary.prop] p8:

> The predicate condition for a template specialization `is_constructible<T, Args...>` shall be satisfied if and only if the following variable definition would be well-formed for some invented variable `t`:

> >     T t(declval<Args>()...);

> [Note: These tokens are never interpreted as a function declaration. — end note]

The problem here is that substituting in `T` as a function type doesn't give a variable definition that's not well-formed (by 3.68 [defns.well.formed], well-formed means that it doesn't violate any syntactic or diagnosable semantic rules, and it does not). Instead, it gives a logical absurdity: this wording forces us to imagine a variable of function type, which contradicts the definition of "variable" in 3/6, but does so without violating any diagnosable language rule. So presumably the result must be undefined behavior.

It seems that we need an explicit rule requiring `T` to be an object or reference type.

Daniel:

As one of the authors of N3142 I would like to express that at least according to my mental model the intention for this trait was to be well-defined for `T` being a function type with the result of `false` regardless of what the other type arguments are. It would seem like a very unfortunate and unnecessary complication to keep the result as being undefined. First, this result value is symmetric to the result of `is_destructible<T>::value` (where the word covers function types explicitly). Second, if such a resolution would be applied to the working paper, it wouldn't break existing implementations. I have tested clang 3.8.0, gcc 5.x until gcc 6.0, and Visual Studio 2015, all of these implementations evaluate `is_constructible<void()>::value` to `false`.

[2016-02, Issues Telecon]

P0; move to Tentatively Ready.

Proposed resolution:

This wording is relative to N4567.

1. Change 21.3.5.4 [meta.unary.prop], Table 49 — "Type property predicates", as indicated:

   > Table 49 — Type property predicates
   > Template | Condition | Preconditions
   > --- | --- | ---
   > `…`
   > `template <class T, class... Args> struct is_constructible;` | For a function type `T`, `is_constructible<T, Args...>::value` is `false`, otherwise see below | `T` and all types in the parameter pack `Args` shall be complete types, (possibly cv-qualified) `void`, or arrays of unknown bound.
   > `…`