You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CWG3122 [temp.dep.constexpr] Inadequate value-dependence for reflect-expressions #808
Issue description
[temp.dep.constexpr]/7.1.4 says that ^^operand is value-dependent when operand names a dependent member of the current instantiation, e.g.,
template <typename T>
structTCls {
static T mem;
staticconstexpr info R = type_of(^^mem); // '^^mem' is value-dependent.
};
This is good, but it doesn't go far enough: If the enclosing template is instead a function template, then the existing conditions for value-dependence fail to apply.
template <typename T>
constevalvoidf() {
T v;
info R = type_of(^^v);
// not currently value-dependent; really needs to be.
}
Annotations are also affected:
template <int K>
intf() {
[[=K]]int v;
returnannotations_of(^^v).size();
// Also not value-dependent, but really ought to be (even though 'v' is neither type nor value dependent).
}
Applying parent_of in such a situation likewise proves a problem. Some of these circumstances would demand that the compiler surface a reflection that represents a dependent type; others become unnecessarily wide IFNDR traps.
Suggested resolution
The reflection of any templated entity (and more: any entity with a declaration in a templated context enclosing the reflect-expression) should be value-dependent.
Modify [temp.dep.constexpr]/7 as follows:
A reflect-expression is value-dependent if
it is of the form ^^reflection-name and either the reflection-nameis
is a dependent qualified name,
is a dependent namespace-name, or
is the name of a template parameter , or
names a dependent member of the current instantiation ([temp.dep.type]),
or lookup for the reflection-name finds a declaration that inhabits a scope corresponding to a templated entity,
it is of the form ^^type-id and the type-id denotes a dependent type, or
it is of the form ^^id-expression and the id-expression is value-dependent.
Note that the value-dependent id-expression bullet remains necessary to handle the case when the operand is a template-id (which is not a reflection-name), e.g.,
template <typename T>
staticconstexpr T zero = 0;
template <typename T>
unsignedf() {
returnsize_of(^^zero<T>);
// 'zero<T>' is a value-dependent id-expression that is not a reflect-expression.
}
I'm thinking of from within the block scope that the declaration inhabits, e.g.,
template <int>
boolf() {
voidg(int a);
returnhas_identifier(parameters_of(^^g)[0]);
}
voidg(int b); // poisons 'has_identifier' for the first parameterbool b = f<0>();
// Well-defined as 'false' if '^^g' is value-dependent; IFNDR if it isn't.
changed the title [-][temp.dep.constexpr] Inadequate value-dependence for reflect-expressions[/-][+]CWG3122 [temp.dep.constexpr] Inadequate value-dependence for reflect-expressions[/+]on Nov 17, 2025
Ah, thanks - missed/forgot that. In that case, "templated entity" covers all cases, but I think it's too broad; we don't want to make reflections that represent non-dependent templates value-dependent:
template <auto V>
voidf() {
int v;
staticconstexprauto r = ^^v; // <- want this to be value-dependent in the template-definitionstaticconstexprauto s = ^^::template f; // <- this is not value-dependent, even though the operand is a templated entity.
};
So maybe we stick with the original suggestion? The "declarations" to which it refers will only be those of templated entities, but it will evolve forwards well, if we later loosen the block-scope restrictions.
If we were to go with "a templated entity other than a template", what would be different?
Anything using a dependent qualified name is already covered.
template<class T>
struct S {
template<class U> struct X;
void f() {
static constexpr auto s = ^^X; // value-dependent?
}
};
Activity
jensmaurer commentedon Nov 17, 2025
I think declarations inside templated entities declare themselves templated entities.
katzdm commentedon Nov 17, 2025
I phrased it that way because I think that block-scope functions and extern variables slip past the definition of "template entity".
jensmaurer commentedon Nov 17, 2025
But we don't (want to) have reflection on those anyway, right?
katzdm commentedon Nov 17, 2025
I'm thinking of from within the block scope that the declaration inhabits, e.g.,
jensmaurer commentedon Nov 17, 2025
That
^^gis ill-formed per the EWG direction for CWG3065.jensmaurer commentedon Nov 17, 2025
CWG3122
[-][temp.dep.constexpr] Inadequate value-dependence for reflect-expressions[/-][+]CWG3122 [temp.dep.constexpr] Inadequate value-dependence for reflect-expressions[/+]katzdm commentedon Nov 17, 2025
Ah, thanks - missed/forgot that. In that case, "templated entity" covers all cases, but I think it's too broad; we don't want to make reflections that represent non-dependent templates value-dependent:
So maybe we stick with the original suggestion? The "declarations" to which it refers will only be those of templated entities, but it will evolve forwards well, if we later loosen the block-scope restrictions.
jensmaurer commentedon Nov 19, 2025
If we were to go with "a templated entity other than a template", what would be different?
Anything using a dependent qualified name is already covered.
Do we want this to be value-dependent?
jensmaurer commentedon Nov 19, 2025
Add-on question: The "inhabits a scope for a templated entity" wording makes the friend case dependent, too:
I guess we want reliable parameter name poisoning here, so ^^f needs to be value-dependent.
katzdm commentedon Nov 19, 2025
Yes, I think it's desirable that both of the above are value-dependent.