This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Open status.
Section: 21 [meta] Status: Open Submitter: Daniel Krügler Opened: 2013-09-02 Last modified: 2016-01-28
Priority: 3
View other active issues in [meta].
View all other issues in [meta].
View all issues with Open status.
Discussion:
The current library specification uses at several places wording that is intended to refer to core language template deduction failure at the top-level of expressions (aka "SFINAE"), for example:
The expression
declval<T>() = declval<U>()
is well-formed when treated as an unevaluated operand (Clause 5). Access checking is performed as if in a context unrelated toT
andU
. Only the validity of the immediate context of the assignment expression is considered. [Note: The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the "immediate context" and can result in the program being ill-formed. — end note]
Similar wording can be found in the specification of result_of
, is_constructible
, and is_convertible
,
being added to resolve an NB comment by LWG 1390(i) and 1391(i) through
N3142.
[2014-05-19, Daniel suggests a descriptive term]
constrictedly well-formed expression:
An expression e depending on a set of typesA1
, ..., An
which is well-formed when treated as
an unevaluated operand (Clause 5). Access checking is performed as if in a context unrelated to A1
, ...,
An
. Only the validity of the immediate context of e is considered. [Note: The compilation of
the expression can result in side effects such as the instantiation of class template specializations and function
template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the
"immediate context" and can result in the program being ill-formed. — end note]
[2014-05-20, Richard and Jonathan suggest better terms]
Richard suggested "locally well-formed"
Jonathan suggested "contextually well-formed" and then "The expression ... is valid in a contrived argument deduction context"[2014-06-07, Daniel comments and improves wording]
The 2014-05-19 suggestion did only apply to expressions, but there are two important examples that are not expressions, but instead
are involving an object definition (std::is_constructible
) and a function definition
(std::is_convertible
), respectively, instead. Therefore I suggest to rephrase the usage of "expression" into "program
construct" in the definition of Jonathan's suggestion of "valid in a contrived argument deduction context".
**Insertable
,
EmplaceConstructible
, and Erasable
definitions in 23.2.2 [container.requirements.general], but given that
these are not fully described in terms of the aforementioned wording yet, I would recommend to fix them by a separate issue
once the committee has agreed on following the suggestion presented by this issue.
[2015-05-05 Lenexa: Move to Open]
...
MC: I think we like the direction but it isn't quite right: it needs some work
JW: I'm prepared to volunteer to move that further, hopefully with the help of Daniel
Roger Orr: should this be Core wording because it doesn't really have anything to do with libraries - the term could then just be used here
AM: Core has nothing to deal with that, though
HT: it seems there is nothing to imply that allows dropping out with an error - maybe that's a separate issue
MC: I'm not getting what you are getting at: could you write an issue? - any objection to move to Open?
...
Proposed resolution:
This wording is relative to N3936.
Add the following new definition to [definitions] as indicated:
valid in a contrived argument deduction context [defns.valid.contr.context]
A program construct c depending on a set of typesA1
, ..., An
, and treated as
an unevaluated operand (Clause 5) when c is an expression, which is well-formed.
Access checking is performed as if in a context unrelated to A1
, ..., An
.
Only the validity of the immediate context (13.10.3 [temp.deduct]) of c is considered.
[Note: The compilation of c can result in side effects such as the instantiation of class template
specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the "immediate context" and can result in the program being ill-formed. —
end note].
Change Table 49 ("Type property predicates") as indicated:
Table 49 — Type property predicates Template Condition Preconditions …
template <class T, class U>
struct is_assignable;The expression declval<T>() =
is valid in a
declval<U>()
contrived argument deduction context
([defns.valid.contr.context]) for types
T
andU
.well-formed when treated
as an unevaluated operand
(Clause 5). Access
checking is performed as if
in a context unrelated toT
andU
. Only the validity of
the immediate context of
the assignment expression
is considered. [Note: The
compilation of the
expression can result in
side effects such as the
instantiation of class
template specializations
and function template
specializations, the
generation of
implicitly-defined
functions, and so on. Such
side effects are not in the
"immediate context" and
can result in the program
being ill-formed. — end
note][…] …
Change 21.3.5.4 [meta.unary.prop] p7 as indicated:
-7- Given the following function prototype:
template <class T> add_rvalue_reference_t<T> create() noexcept;the predicate condition for a template specialization
is_constructible<T, Args...>
shall be satisfied if and only if the following variable definitionwould be well-formedfor some invented variablet
would be valid in a contrived argument deduction context ([defns.valid.contr.context]) for typesT
andArgs...
:T t(create<Args>()...);[Note: These tokens are never interpreted as a function declaration. — end note]
Access checking is performed as if in a context unrelated toT
and any of theArgs
. Only the validity of the immediate context of the variable initialization is considered. [Note: The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the "immediate context" and can result in the program being ill-formed. — end note]
Change Table 57 ("Other transformations") as indicated:
Table 57 — Other transformations Template Condition Comments …
template <class Fn, class... ArgTypes>
struct result_of<Fn(ArgTypes...)>;[…] If the expression
INVOKE(declval<Fn>(),
is
declval<ArgTypes>()...)
valid in a contrived argument deduction
context ([defns.valid.contr.context]) for types
Fn
andArgTypes...
well, the
formed when treated as an
unevaluated operand (Clause 5)
member typedef type shall name the
type
decltype(INVOKE(declval<Fn>(),
;
declval<ArgTypes>()...))
otherwise, there shall be no member
type.Access checking is performed as
if in a context unrelated toFn
and
ArgTypes
. Only the validity of the
immediate context of the expression is
considered. [Note: The compilation of
the expression can result in side
effects such as the instantiation of
class template specializations and
function template specializations, the
generation of implicitly-defined
functions, and so on. Such side effects
are not in the "immediate context"
and can result in the program being
ill-formed. — end note]…
Change 21.3.7 [meta.rel] p4 as indicated:
-4- Given the following function prototype:
template <class T> add_rvalue_reference_t<T> create() noexcept;the predicate condition for a template specialization
is_convertible<From, To>
shall be satisfied if and only if the return expression in the following code would bewell-formedvalid in a contrived argument deduction context ([defns.valid.contr.context]) for typesTo
andFrom
, including any implicit conversions to the return type of the function:To test() { return create<From>(); }[Note: This requirement gives well defined results for reference types,
void
types, array types, and function types. — end note]Access checking is performed as if in a context unrelated toTo
andFrom
. Only the validity of the immediate context of the expression of the return-statement (including conversions to the return type) is considered. [Note: The evaluation of the conversion can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the "immediate context" and can result in the program being ill-formed. — end note]