Topic: On the entity of template nontype parameters


Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Thu, 19 Aug 2010 02:12:00 CST
Raw View
Given this example:

template<int const I>
struct A {
 decltype(I) m;
};

A<0> a; // ill-formed or not?

First, what kind of entity is I? I can't see it fit into anything of the
list in clause 3. One might be inclined to say it's a "value" entity, but a
template parameter is more than that in my feeling (enumerators also are own
entities) since they can be dependent and such.

Then, what type does "decltype(I)" designate? C++0x says

"If e is an unparenthesized id-expression or a class member access (5.2.5),
decltype(e) is the type of the entity named by e."

(this is problematic by itself, because it requires runtime knowledge - what
is the type of an arbitrary object referred? We can't know! We only know its
declared type!). And on the type of that entity (let's assume there is a
"template parameter" entity), 14.2/4 says:

"The top-level cv-qualifiers on the template-parameter are ignored
when determining its type."

and the previous paragraph says, contradictory (it does not say "shall be
*declared* with one ...", but it actually talks about the type of the
parameter itself).

"A non-type template-parameter shall have one of the following (optionally
cv-qualified) types."

So is the type of the entity "const int" or "int"?

This probably suggests that "template parameter" should be part of the
entity list. And that statement in 14.2/4 should imho be removed, because
the Standard is clear elsewhere that prvalues of non-class type are never
cv-qualified.

Any comments?


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =3D?ISO-8859-1?Q?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Date: Fri, 20 Aug 2010 10:32:32 CST
Raw View
On 19 Aug., 10:12, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Given this example:
>
> template<int const I>
> struct A {
>  decltype(I) m;
> };
>
> A<0> a; // ill-formed or not?

It is well-formed, because decltype(I) is int (not const int),
see 14.1/6:

"A non-type non-reference template-parameter is a prvalue."

combined with p. 5

"The top-level cv-qualifiers on the template-parameter are
ignored when determining its type."

and with 3.10/4:

"non-class prvalues always have cv-unqualified types"

> First, what kind of entity is I? I can't see it fit into anything of the
> list in clause 3. One might be inclined to say it's a "value" entity, but
a
> template parameter is more than that in my feeling (enumerators also
> are own entities) since they can be dependent and such.

They are values.

> Then, what type does "decltype(I)" designate? C++0x says
>
> "If e is an unparenthesized id-expression or a class member access
(5.2.5),
> decltype(e) is the type of the entity named by e."
>
> (this is problematic by itself, because it requires runtime knowledge -
what
> is the type of an arbitrary object referred? We can't know! We only know
its
> declared type!).

Can you give a specific example, where this would make a difference?
Bullet 1 is already constraining several situations where this would
matter.

> And on the type of that entity (let's assume there is a
> "template parameter" entity), 14.2/4 says:
>
> "The top-level cv-qualifiers on the template-parameter are ignored
> when determining its type."
>
> and the previous paragraph says, contradictory (it does not say "shall be
> *declared* with one ...", but it actually talks about the type of the
> parameter itself).
>
> "A non-type template-parameter shall have one of the following (optionall=
y
> cv-qualified) types."
>
> So is the type of the entity "const int" or "int"?

It is int. The category "contradictory" looks too strong to me,
though. I agree that using the word "declared" would improve
the status quo.

In this context it is interesting to reconsider the current wording
state, because it would cause a difference, when the language
would allow for literal (class) types as valid template parameters.
It is also in disagreement in a current ongoing clarification on
the cv-qualified nature of function parameters as of [dcl.fct].

> This probably suggests that "template parameter" should be part of the
> entity list.

Currently there is no reason to do so, as far as I see.

> And that statement in 14.2/4 should imho be removed, because
> the Standard is clear elsewhere that prvalues of non-class type are never
> cv-qualified.

There is nothing wrong with the note, as far as I see. As usual
you have a lot of freedom to decide to add a note or not. In
the end this is a rather subjective decision.

HTH & Greetings from Bremen,

Daniel Kr=FCgler


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Gennaro Prota <gennaro.prota@yahoo.com>
Date: Fri, 20 Aug 2010 10:31:52 CST
Raw View
On 19/08/2010 10.12, Johannes Schaub (litb) wrote:
> Given this example:
>
> template<int const I>
> struct A {
>  decltype(I) m;
> };
>
> A<0> a; // ill-formed or not?
>
> First, what kind of entity is I? I can't see it fit into anything of the
> list in clause 3. One might be inclined to say it's a "value" entity, but
a
> template parameter is more than that in my feeling (enumerators also are
own
> entities) since they can be dependent and such.
>
> Then, what type does "decltype(I)" designate? C++0x says
>
> "If e is an unparenthesized id-expression or a class member access
(5.2.5),
> decltype(e) is the type of the entity named by e."
>
> (this is problematic by itself, because it requires runtime knowledge -
what
> is the type of an arbitrary object referred? We can't know! We only know
its
> declared type!). And on the type of that entity (let's assume there is a
> "template parameter" entity), 14.2/4 says:
>
> "The top-level cv-qualifiers on the template-parameter are ignored
> when determining its type."
>
> and the previous paragraph says, contradictory (it does not say "shall be
> *declared* with one ...", but it actually talks about the type of the
> parameter itself).
>
> "A non-type template-parameter shall have one of the following (optionally
> cv-qualified) types."
>
> So is the type of the entity "const int" or "int"?
>
> This probably suggests that "template parameter" should be part of the
> entity list. And that statement in 14.2/4 should imho be removed, because
> the Standard is clear elsewhere that prvalues of non-class type are never
> cv-qualified.
>
> Any comments?

Yes. And my comment is: don't go to that level of precision with
the C++ standard. If I did this I'd file four DRs a day. And it
takes *years* to the committee to come up with a new wording
which supposedly fixes the issue.

So the final effect is just consuming time.

It's unfortunate, I agree. But that's it. Nowadays I only submit
issues that affect real code and need to be resolved one way or
another in order e.g. to provide sensible guarantees. I'm going
to post something about the new alignment paragraph, for
instance, because among other things it assumes that any
alignment is a power of two with a non-negative integer exponent
without saying so in normative text; and doesn't clarify some
useful things for user code. But other than that... Just think
that they don't even use "if and only if" (but just "if") where
it would be opportune.

--
 Gennaro Prota         |           name.surname yahoo.com
   Breeze C++ (preview): <https://sourceforge.net/projects/breeze/>
   Do you need expertise in C++?   I'm available.

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Fri, 20 Aug 2010 16:27:39 CST
Raw View
Johannes Schaub (litb) wrote:

> Given this example:
>
> template<int const I>
> struct A {
>  decltype(I) m;
> };
>
> A<0> a; // ill-formed or not?
>
> First, what kind of entity is I? I can't see it fit into anything of the
> list in clause 3. One might be inclined to say it's a "value" entity, but
> a template parameter is more than that in my feeling (enumerators also are
> own entities) since they can be dependent and such.
>
> Then, what type does "decltype(I)" designate? C++0x says
>
> "If e is an unparenthesized id-expression or a class member access
> (5.2.5), decltype(e) is the type of the entity named by e."
>
> (this is problematic by itself, because it requires runtime knowledge -
> what is the type of an arbitrary object referred? We can't know! We only
> know its declared type!). And on the type of that entity (let's assume
> there is a "template parameter" entity), 14.2/4 says:
>
> "The top-level cv-qualifiers on the template-parameter are ignored
> when determining its type."
>
> and the previous paragraph says, contradictory (it does not say "shall be
> *declared* with one ...", but it actually talks about the type of the
> parameter itself).
>
> "A non-type template-parameter shall have one of the following (optionally
> cv-qualified) types."
>
> So is the type of the entity "const int" or "int"?
>
> This probably suggests that "template parameter" should be part of the
> entity list. And that statement in 14.2/4 should imho be removed, because
> the Standard is clear elsewhere that prvalues of non-class type are never
> cv-qualified.
>

I didn't think enough about 14.2/4. It should probably *not* be removed.
It's needed to make these things work:

template<int const I> struct B { };

// #1 types match: const ignored
template<int I> void f(B<I>) { }

// #2 appears in another TU: should linked against the first f!
template<int const I> void f(B<I>);

However, it still seems to me that clearer wording is needed. E.g what tells
us that decltype does not "determine" the type of the parameter by ignoring
const likewise?

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Fri, 20 Aug 2010 17:04:50 CST
Raw View
=?ISO-8859-1?Q?Daniel_Kr=FCgler?= wrote:

> On 19 Aug., 10:12, "Johannes Schaub (litb)" <schaub-johan...@web.de>
> wrote:
>> Given this example:
>>
>> template<int const I>
>> struct A {
>>  decltype(I) m;
>> };
>>
>> A<0> a; // ill-formed or not?
>
> It is well-formed, because decltype(I) is int (not const int),
> see 14.1/6:
>
> "A non-type non-reference template-parameter is a prvalue."
>
> combined with p. 5
>
> "The top-level cv-qualifiers on the template-parameter are
> ignored when determining its type."
>
> and with 3.10/4:
>
> "non-class prvalues always have cv-unqualified types"
>

You are arguing with expresion types (prvalues), but "decltype(I)" does not
inspect the expression, but rather the entity named. Your point applies to
"decltype((I))".

>> First, what kind of entity is I? I can't see it fit into anything of the
>> list in clause 3. One might be inclined to say it's a "value" entity, but
> a
>> template parameter is more than that in my feeling (enumerators also
>> are own entities) since they can be dependent and such.
>
> They are values.
>

I can't comment this, because i'm not completely understanding the
motivations when and when not to put something as an entity there. But in
this case it seems weird to make it "just" a value.

>> Then, what type does "decltype(I)" designate? C++0x says
>>
>> "If e is an unparenthesized id-expression or a class member access
> (5.2.5),
>> decltype(e) is the type of the entity named by e."
>>
>> (this is problematic by itself, because it requires runtime knowledge -
> what
>> is the type of an arbitrary object referred? We can't know! We only know
> its
>> declared type!).
>
> Can you give a specific example, where this would make a difference?
> Bullet 1 is already constraining several situations where this would
> matter.
>

In the following code, the object designated by "...->a" has type "const
int", but the declared type of A::a is "int". The Standard requires this to
give "const int" currently, because that's the type of the object named.

struct A {
 int a;
};

// type of object designated: const int
// type of declaration named by second operand: int
// type of expression: const int
decltype((new A const())->a) b;

Another issue is on incomplete arrays: An incomplete array may have a
declared type that is int[], but the object named by its declaration cannot
have type int[] at all.

The phrase "declared type" may be difficult to justify for named function
template specializations i suspect, though. But it would be clear what the
Standard would mean, in my opinion much clearer than it is currently.

Similar, tho this is more theoretical now, what about this code?

// type of the object designated: no object designated!
// type of declaration named by second operand: int
// type of expression: int
decltype(((A*)0)->a) b;

That said, i'm unsure about the two entities "class member" and "object". We
can apply both entity types here - which one shall we choose, and does it
make any difference? Thanks for your insights.

>
>> And that statement in 14.2/4 should imho be removed, because
>> the Standard is clear elsewhere that prvalues of non-class type are never
>> cv-qualified.
>
> There is nothing wrong with the note, as far as I see. As usual
> you have a lot of freedom to decide to add a note or not. In
> the end this is a rather subjective decision.
>

Please see my follow-up post to my question. There are some paragraphs that
depend on const being ignored to "determine" the type of the parameter, so i
would not think anymore that this note could be removed.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]