is_*[copy/move]_[constructible/assignable]
unclear for non-referencable typesSection: 21.3.5.4 [meta.unary.prop] Status: C++14 Submitter: Daniel Krügler Opened: 2012-10-06 Last modified: 2016-01-28
Priority: Not Prioritized
View other active issues in [meta.unary.prop].
View all other issues in [meta.unary.prop].
View all issues with C++14 status.
Discussion:
The pre-conditions for the type is_copy_constructible
allow for template argument types were the language forbids
forming a reference, namely void
types and function types that have cv-qualifiers or a ref-qualifier.
is_constructible<T, const T&>::value
istrue
.
leaves it open whether such argument types would (a) create a well-formed instantiation of the trait template or if so (b) what
the outcome of the trait evaluation would be, as an example consider std::is_copy_constructible<void>
.
void
type or of function type at all, so it would be surprising
to return a positive result for copy or move construction if no other construction could succeed. It is also not
possible to assign to a any of these values (because there is no way to form lvalues of them), so the same argumentation
can be applied to the is_copy/move_assignable
traits as well.
To reduce the amount of wording changes and repetitions, I suggest to define the term referenceable type in
sub-clause [definitions] or alternatively in the core language to describe types to which references
can be created via a typedef name. This definition corresponds to what the support concept ReferentType
intended
to describe during concept time.
In addition, LWG issue 2101 can also take advantage of the definition of a referenceable type.
If the proposed resolution for LWG issue 2101 would be accepted, there is an alternative solution possible
with the same effects. Now we would be able to use the now always well-formed instantiation of
std::add_lvalue_reference
to modify the current definition of is_copy_constructible
to
is_constructible<T,
is true.
typename add_lvalue_reference<
typename add_const<T>::type>::type>::value
and similar changes for the other affected traits.
[2012-10 Portland: Move to Open]
Referencable-type should be defined as "something that can be bound into a reference" or similar, rather than a list of types where that is true today. We can then provide the list of known types that cannot be bound as examples that do not qualify in a note.
Otherwise we are happy with the wording. AJM to redraft the definition and move to Review.
[2013-04-18, Bristol]
Proposed resolution:
This wording is relative to N3376.
Add the following new definition to [definitions] as indicated:
referenceable type [defns.referenceable]
An object type, a function type that does not have cv-qualifiers or a ref-qualifier, or a reference type. [Note: The term describes a type to which a reference can be created, including reference types. — end note]
Change Table 49 as indicated:
Template | Condition | Preconditions |
---|---|---|
template <class T> struct is_copy_constructible;
|
For a referenceable type T , the same result asis_constructible<T, const T&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
template <class T> struct is_move_constructible;
|
For a referenceable type T , the same result asis_constructible<T, T&&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
…
|
||
template <class T> struct is_copy_assignable;
|
For a referenceable type T , the same result asis_assignable<T&, const T&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
template <class T> struct is_move_assignable;
|
For a referenceable type T , the same result asis_assignable<T&, T&&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
…
|
||
template <class T> struct is_trivially_copy_constructible;
|
For a referenceable type T , the same result asis_trivially_constructible<T, const T&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
template <class T> struct is_trivially_move_constructible;
|
For a referenceable type T , the same result asis_trivially_constructible<T, T&&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
…
|
||
template <class T> struct is_trivially_copy_assignable;
|
For a referenceable type T , the same result asis_trivially_assignable<T&, const T&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
template <class T> struct is_trivially_move_assignable;
|
For a referenceable type T , the same result asis_trivially_assignable<T&, T&&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
…
|
||
template <class T> struct is_nothrow_copy_constructible;
|
For a referenceable type T , the same result asis_nothrow_constructible<T, const T&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
template <class T> struct is_nothrow_move_constructible;
|
For a referenceable type T , the same result asis_nothrow_constructible<T, T&&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
…
|
||
template <class T> struct is_nothrow_copy_assignable;
|
For a referenceable type T , the same result asis_nothrow_assignable<T&, const T&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |
template <class T> struct is_nothrow_move_assignable;
|
For a referenceable type T , the same result asis_nothrow_assignable<T&, T&&>::value |
T shall be a complete type,(possibly cv-qualified) void , or anarray of unknown bound. |