Skip to content

[expr.prim.splice] Should variable-template splice specializations be constified in contract predicates? #9172

Description

@abhinavagarwal07

Subclause: [expr.prim.splice]

P3598R0, resolving CWG3158, added contract-predicate constification for the plain splice-specifier form. However, the variable-template splice-specialization-specifier form from P2996R13 still says unconditionally that the expression has the same type as the selected specialization.

For example:

template<int I> int var = I;

void f()
  pre(template [:^^var:]<0> == 0) // not constified: template splice-specialization-specifier
  pre([:^^var<0>:] == 0);         // constified: plain splice-specifier
Expression What is inside [: ... :]
template [:^^var:]<0> Template var; <0> is outside the splice
[:^^var<0>:] Specialization var<0>; <0> is inside the splice

Both expressions refer to var<0>. Is this difference intentional?


The difference affects well-formedness: only the specialization form can be used to modify the variable within the predicate.

void g()
  pre((template [:^^var:]<0> = 1)) // well-formed: non-const lvalue, assignable
  pre(([:^^var<0>:] = 1));        // ill-formed: const lvalue

If not, should the variable-template branch in [expr.prim.splice] apply the same shallow constification rule when the expression appears in a contract predicate?

Separately, that branch still says only “the object associated with S”. A reference variable-template specialization can instead refer to a function. That wording alignment seems independent of the constification question.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions