is_trivially_constructible/is_trivially_assignable
traits are always falseSection: 21.3.5.4 [meta.unary.prop] Status: C++17 Submitter: Daniel Krügler Opened: 2013-10-01 Last modified: 2017-07-30
Priority: 3
View other active issues in [meta.unary.prop].
View all other issues in [meta.unary.prop].
View all issues with C++17 status.
Discussion:
In 21.3.5.4 [meta.unary.prop] we have traits to allow testing for triviality of specific operations, such as
is_trivially_constructible
and is_trivially_assignable
(and their derived forms), which are specified
in terms of the following initialization and assignment, respectively:
T t(create<Args>()...); declval<T>() = declval<U>()
The wording that describes the way how triviality is deduced, is in both cases of the same form:
[… ] and the variable definition/assignment, as defined by
is_constructible/is_assignable
, is known to call no operation that is not trivial (3.9, 12).
The problematic part of this wording is that both definitions are specified in terms of an "object construction" function
create
or declval
, respectively, (The former being a conceptual function, the latter being a library function),
but for none of these functions we can assume that they could be considered as trivial — only special member functions can
have this property and none of these is one. This problem became obvious, when the similar issue LWG 2298
in regard to is_nothrow_constructible
was opened.
create
, which
is currently needed for the is_convertible
and the is_constructible
traits, because both traits are specified in
terms of contexts where technically the corresponding "object construction" function would be considered as odr-used. This is problematic,
because these traits are defined in terms of well-formed code and odr-using declval
would make the program ill-formed (see
22.2.6 [declval]). So extending above blanket statement to consider std::declval<T>()
as not odr-used
in the context of the corresponding trait definition would allow for replacing create
by declval
.
[2015-05, Lenexa]
STL: would you consider moving the change to 20.10 as editorial or are you uncomfortable with it?
JW: this sounds a viable editorial change
VV: I guarantee you that moving it doesn't change anything
MC: how about this: we move it to Ready as is and if we conclude moving it is editorial we can do it and if not open an issue
STL: I would like to guarantee that the lifting happens
JW: I do that! If it goes in I move it up
MC: move to Ready: in favor: 15, opposed: 0, abstain: 1
Proposed resolution:
This wording is relative to N3936.
Add a new paragraph after 21.3.5.4 [meta.unary.prop] p3 as indicated: [Editorial note: The first change in 21.3.5.4 [meta.unary.prop] p3 is recommended, because technically a Clause is always a "main chapter" — such as Clause 20 — but every child of a Clause or sub-clause is a sub-clause]
[…]
-3- For all of the class templatesX
declared in thisClausesub-clause, instantiating that template with a template-argument that is a class template specialization may result in the implicit instantiation of the template argument if and only if the semantics ofX
require that the argument must be a complete type. -?- For the purpose of defining the templates in this sub-clause, a function call expressiondeclval<T>()
for any typeT
is considered to be a trivial (6.8 [basic.types], 11.4.4 [special]) function call that is not an odr-use (6.3 [basic.def.odr]) ofdeclval
in the context of the corresponding definition notwithstanding the restrictions of 22.2.6 [declval]. […]
Modify 21.3.5.4 [meta.unary.prop] p7 as indicated:
-7-
Given the following function prototype:template <class T> typename add_rvalue_reference<T>::type create();
tThe predicate condition for a template specializationis_constructible<T, Args...>
shall be satisfied if and only if the following variable definition would be well-formed for some invented variablet
:T t(createdeclval<Args>()...);[…]
Add a new paragraph after 21.3.7 [meta.rel] p2 as indicated: [Editorial note: Technically we don't need the guarantee of "a trivial function call" for the type relationship predicates at the very moment, but it seems more robust and consistent to have the exact same guarantee here as well]
[…]
-2- […] -?- For the purpose of defining the templates in this sub-clause, a function call expressiondeclval<T>()
for any typeT
is considered to be a trivial (6.8 [basic.types], 11.4.4 [special]) function call that is not an odr-use (6.3 [basic.def.odr]) ofdeclval
in the context of the corresponding definition notwithstanding the restrictions of 22.2.6 [declval]. […]
Modify 21.3.7 [meta.rel] p4 as indicated:
-4-
Given the following function prototype:template <class T> typename add_rvalue_reference<T>::type create();
tThe predicate condition for a template specializationis_convertible<From, To>
shall be satisfied if and only if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function:To test() { returncreatedeclval<From>(); }[…]