This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Ready status.

4536. Type traits have inconsistent interactions with immediate functions

Section: 21.3.6.4 [meta.unary.prop], 21.3.8 [meta.rel] Status: Ready Submitter: Tim Song Opened: 2026-03-05 Last modified: 2026-03-06

Priority: Not Prioritized

View other active issues in [meta.unary.prop].

View all other issues in [meta.unary.prop].

View all issues with Ready status.

Discussion:

Per 7.7 [expr.const]p23, calls to immediate functions are not immediate invocations, and therefore are not required to result in constant expressions, if the call occurs in an unevaluated operand. Currently, some type traits (e.g. is_assignable, is_invocable) specify that the construct at issue is treated as an unevaluated operand, while others (is_constructible, is_convertible) do not. This seems like a bad state of affairs.

The wording below makes everything unevaluated (and hence not check for constant-ness) to match the behavior of requires expressions (and implementations). This arguably makes the traits less useful in some contexts where false negatives are tolerable but false positives are not.

[2026-03-06 LWG telecon; move to Ready]

Proposed resolution:

This wording is relative to N5032.

  1. Modify [tab:meta.unary.prop], Table 54 — Type property predicates as indicated:

    TemplateConditionPreconditions
    
    template<class T, class U>
    struct reference_constructs_from_temporary;
    T is a reference type, and the initialization T t(VAL<U>); is well-formed and binds t to a temporary object whose lifetime is extended (6.8.7 [class.temporary]). The full-expression of the variable initialization is treated as an unevaluated operand (7.2.3 [expr.context]). Access checking is performed as if in a context unrelated to T and U. Only the validity of the immediate context of the variable initialization is considered. [Note 5: … — end note] […]
    
    template<class T, class U>
    struct reference_converts_from_temporary;
    T is a reference type, and the initialization T t = VAL<U>; is well-formed and binds t to a temporary object whose lifetime is extended (6.8.7 [class.temporary]). The full-expression of the variable initialization is treated as an unevaluated operand (7.2.3 [expr.context]). Access checking is performed as if in a context unrelated to T and U. Only the validity of the immediate context of the variable initialization is considered. [Note 6: … — end note] […]
  2. Modify 21.3.6.4 [meta.unary.prop] p9 as indicated:

    -9- 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 7: … — end note]

    The full-expression of the variable initialization is treated as an unevaluated operand (7.2.3 [expr.context]). Access checking is performed as if in a context unrelated to T and any of the Args. Only the validity of the immediate context of the variable initialization is considered.

    [Note 8: … — end note]

  3. Modify 21.3.8 [meta.rel] p6 as indicated:

    -9- The predicate condition for a template specialization is_convertible<From, To> shall be satisfied if and only if the return expressionstatement (8.8.4 [stmt.return]) in the following code would be well-formed, including any implicit conversions to the return type of the function:

    To test() {
      return declval<From>();
    }
    

    [Note 4: … — end note]

    Access checking is performed in a context unrelated to To and From. The operand of the return statement (including initialization of the returned object or reference, if any) is treated as an unevaluated operand (7.2.3 [expr.context]), and only the validity of its immediate context is considered. Only the validity of the immediate context of the expression of the return statement (8.8.4 [stmt.return]) (including initialization of the returned object or reference) is considered.

    [Note 5: … — end note]