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.
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.
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 belowT and all types in the
parameter pack Args shall
be complete types,
(possibly cv-qualified)
void, or arrays of
unknown bound.…