is_constructible
underspecified when applied to a function typeSection: 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 variablet
: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.66 [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.
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
isfalse
, otherwise see belowT
and all types in the
parameter packArgs
shall
be complete types,
(possibly cv-qualified)
void
, or arrays of
unknown bound.…