C++ Logo

std-discussion

Advanced search

Unclear template type equivalence for decltype(dependent expression)

From: mauro russo <ing.russomauro_at_[hidden]>
Date: Mon, 11 Nov 2024 22:12:43 +0100
Looking at the current draft exposed by https://eel.is/c++draft/#temp as
generate on 9th of Nov 2024, (as well as since at least the last draft
n4849 for C++20),

§13.6 ([temp.type]) - 5 reads

"If an expression e is type-dependent
<https://eel.is/c++draft/temp.dep.expr>, decltype(e) denotes a unique
dependent type. <https://eel.is/c++draft/temp.type#4.sentence-1>

Two such *decltype-specifier*
<https://eel.is/c++draft/dcl.type.decltype#nt:decltype-specifier>*s* refer
to the same type only if their *expression*
<https://eel.is/c++draft/expr.comma#nt:expression>*s* are equivalent ([temp.
over.link] <https://eel.is/c++draft/temp.over.link>).
<https://eel.is/c++draft/temp.type#4.sentence-2>"

I am not sure whether this wording applies to any context, not just to
template arguments in template-ids (which is the topic of [temp.type]. If
so, some further explicit statement might be added.
I tried to discuss this topic on stack overflow
<https://stackoverflow.com/questions/79040452/unique-dependent-type-for-decltypedependent-expression-in-c>,
but I did not get a complete answer.

Moreover, the comprehension should rely on the clause §13.7.6.1
([temp.over.link]) where the point 5 reads

"Two expressions involving template parameters are considered *equivalent*
<https://eel.is/c++draft/temp.over.link#def:equivalent,expressions> if two
function definitions containing the expressions would satisfy the
one-definition
rule <https://eel.is/c++draft/basic.def.odr>, except that the tokens used
to name the template parameters may differ as long as a token used to name
a template parameter in one expression is replaced by another token that
names the same template parameter in the other expression.
<https://eel.is/c++draft/temp.over.link#5.sentence-1> ..."

Here doubts start more and more.

"if two function definitions containing the expressions..." -> should it
mean in the declarative part only of the definition or even in the body ?
In the former case, does it mean the two expressions have the same role
(e.g., return type, type of the same-index parameter, etc.) ? No other
requirements of 'similarity' for these two functions ? I really believe
more information should be provided about how to construct these two
function definitions, likely starting to indicate that the intent is two
definitions of the same function.

And then, how a function (definition) may be in a scope involving template
parameters except being a template(d) function member of a template(d)
class... that is why not clarifying 'templated' for these two functions ?
The need of clarifying 'templated functions' seems to derive even by the
fact that we are discussing about some 'equivalence', and two different
definitions for the same non-inline non-templated function violates the ODR
rule (regardless of the sequence of tokens: refer §6.3 [basic.def.odr] -
(15.1)).

Additionally, looking at §6.3-(16.3):
"If D is a template and is defined in more than one translation unit, the
requirements apply both to names from the template's enclosing scope used
in the template definition, and also to dependent names at the point of
instantiation ([temp.dep] <https://eel.is/c++draft/temp.dep>).
<https://eel.is/c++draft/basic.def.odr#16.3.sentence-1>"

I guess that problems may arise by using 'templated functions' (in an
eventual fix of §13.7.6.1-5) instead of 'template functions', because
§6.3-(16.3) refers applying requirements to "names from the enclosing
scope" only for templates, not for templated entities. Of course, the
intent of 6.3-(16.3) also implicitly covers the templated entities included
in a template... but for the two hypothetical definitions referred by
§13.7.6.1-5, they appear as 'the starting point', that is, not caring of
any hypothetical enclosing template to which §6.3-(16.3) would be
applicable.

Coming back to §13.6-5, do you really believe that the two templates in the
example of stack overflow
<https://stackoverflow.com/questions/79040452/unique-dependent-type-for-decltypedependent-expression-in-c>
:

X<decltype(t+t)> a;
X<T> b;

should be the same type, and that §13.6-5 correctly supports this
equivalence ? I don't see so, based on the fact that §13.6-5 refers
§13.7.6.1-5 that, in turn, refers §6.3 which finally requires the same
sequence of tokens. Well, §13.7.6.1-5 reads that different parameter naming
is anyway acceptable as relaxation compared to the requirements from §6.3,
but the provided example does not match such an exception. Really, in my
example we have one decltype(e) and one non-decltype, for which §13.6 might
say something more, ... but even using X<decltype(t+t+t)> for 'b' object, I
still get the same type from several compilers, a comprehensible intent for
the language, likely supported by the aforementioned standard clauses in a
non-very clear manner.

Just to assure to provide the link to the example from stack overflow:
https://stackoverflow.com/questions/79040452/unique-dependent-type-for-decltypedependent-expression-in-c

Received on 2024-11-11 21:12:57