C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Dependent names in typeid expressions

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Scott Meyers
Guest





PostPosted: Thu Jul 01, 2004 7:57 pm    Post subject: Dependent names in typeid expressions Reply with quote



Dependent type names must always be preceded by "typename", right? So
consider:

template<typename T>
void foo()
{
if (typeid(std::list<T>::iterator) == typeid(int));
}

gcc 3.2 issues a warning about the lack of "typename" in front of
std::list<T>::iterator, but VC7.1 and Comeau 4.3.3 accept the code without
complaint. Is there something special going on here, are VC7.1 and Comeau
simply wrong, or is my understanding of typename and dependent names
wanting?

Thanks,

Scott

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Sergiy Kanilo
Guest





PostPosted: Thu Jul 01, 2004 9:25 pm    Post subject: Re: Dependent names in typeid expressions Reply with quote




"Scott Meyers" <Usenet (AT) aristeia (DOT) com> wrote

Quote:
Dependent type names must always be preceded by "typename", right? So
consider:

template<typename T
void foo()
{
if (typeid(std::list }

gcc 3.2 issues a warning about the lack of "typename" in front of
std::list<T>::iterator, but VC7.1 and Comeau 4.3.3 accept the code without
complaint. Is there something special going on here, are VC7.1 and Comeau
simply wrong, or is my understanding of typename and dependent names
wanting?

14.6.2.2
/4 Expressions of the following forms are never type-dependent
...
typeid ( expression )
typeid ( typeid )
...

Cheers,
Serge


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Scott Meyers
Guest





PostPosted: Thu Jul 01, 2004 11:45 pm    Post subject: Re: Dependent names in typeid expressions Reply with quote



On 1 Jul 2004 21:25:14 GMT, Sergiy Kanilo wrote:
Quote:
14.6.2.2
/4 Expressions of the following forms are never type-dependent
..
typeid ( expression )
typeid ( typeid )
..

That may be true, but I don't see anything in that section that overrules
14.6/2:

A name used in a template declaration or definition and that is dependent
on a template-parameter is assumed not to name a type unless the
applicable name lookup finds a type name or the name is qualified by the
keyword typename.

On the other hand, I don't understand the significance of type-dependent
expressions (14.6.2.2), and they're surely defined for a reason.

Scott

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Hyman Rosen
Guest





PostPosted: Fri Jul 02, 2004 3:12 pm    Post subject: Re: Dependent names in typeid expressions Reply with quote

Scott Meyers wrote:
Quote:
Dependent type names must always be preceded by "typename", right? So
consider:

template<typename T> void foo()
{ if (typeid(std::list<T>::iterator) == typeid(int)); }

gcc 3.2 issues a warning about the lack of "typename" in front of
std::list<T>::iterator, but VC7.1 and Comeau 4.3.3 accept the code without
complaint. Is there something special going on here, are VC7.1 and Comeau
simply wrong, or is my understanding of typename and dependent names
wanting?

If you leave out the typename, then the dependent name is assumed
to not be a type. But it's perfectly OK to take typeid of non-types!
Now, 14.6/3 says that a dependent name which denotes a type "shall"
be preceeded by typename, so this imposes a requirement on you.
Further, 14.6/4 says that if you did use typename but the name is
not a type, the program is ill-formed. But it does not say that for
the converse case, where you did not use a typename but the name is
a type. So the compilers are perfectly within their rights to say
nothing and just accept the code. That's my analysis.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
David Abrahams
Guest





PostPosted: Fri Jul 02, 2004 3:14 pm    Post subject: Re: Dependent names in typeid expressions Reply with quote

Scott Meyers <Usenet (AT) aristeia (DOT) com> writes:

Quote:
Dependent type names must always be preceded by "typename", right?

Almost. Not in base class lists and a few other places, like
qualified non-dependent names inside a template (allowed but not
required) and typename is forbidden on unqualified names like
"pair<int,T>" and on explicit template specializations. There's an
appendix that explains all this stuff in the appendix of "C++ Template
Metaprogramming", to which you have access.

Quote:
So
consider:

template<typename T
void foo()
{
if (typeid(std::list }

gcc 3.2 issues a warning about the lack of "typename" in front of
std::list<T>::iterator, but VC7.1 and Comeau 4.3.3 accept the code without
complaint. Is there something special going on here, are VC7.1 and Comeau
simply wrong, or is my understanding of typename and dependent names
wanting?

Recall what typeid is about: it helps the parser distinguish the names
of types from those of objects. At the point foo is parsed, the
compiler doesn't know whether std::list<X> is defined this way:

template <>
struct list<X>
{
typedef int iterator; // a type
...
};

or this way:

template <>
struct list<X>
{
static int iterator; // an object
...
};

Even though the compiler has seen the primary template, a
specialization could come along later and change the meaning of
std::list<X>::iterator for any given X. It so happens that typeid
works on both types and on expressions, so either one would be
valid.

Comeau doesn't seem to warn if you instantiate foo<int> later either,
but that's because EDG only uses the first phase of template
compilation (the one where typename takes effect) to issue
diagnostics. In order to maintain a "broken compiler with only
one-phase lookup" mode they have to be able to do all the work at the
point of instantiation anyway, so that's what they always do. If they
were saving the parse tree from phase 1 you'd get an error at
instantiation time when std::list<T>::iterator turned out to be a
type.

HTH,

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
David Abrahams
Guest





PostPosted: Fri Jul 02, 2004 7:48 pm    Post subject: Re: Dependent names in typeid expressions Reply with quote

"Sergiy Kanilo" <skanilo (AT) artannlabs (DOT) com> writes:

Quote:
14.6.2.2
/4 Expressions of the following forms are never type-dependent
..
typeid ( expression )
typeid ( typeid )
..

Cheers,
Serge

True, but irrelevant IMO. The fact that typeid( xxxx ) is not
type-dependent doesn't mean that xxxx itself isn't type-dependent.
The situation is no different from:

template <class T>
struct foo
{
enum { value = sizeof(typename std::list<int>::iterator) };
};

Where typename is indeed required.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Sergiy Kanilo
Guest





PostPosted: Fri Jul 02, 2004 7:48 pm    Post subject: Re: Dependent names in typeid expressions Reply with quote


"Scott Meyers" <Usenet (AT) aristeia (DOT) com> wrote

Quote:
On 1 Jul 2004 21:25:14 GMT, Sergiy Kanilo wrote:
14.6.2.2
/4 Expressions of the following forms are never type-dependent
..
typeid ( expression )
typeid ( typeid )
..

That may be true, but I don't see anything in that section that overrules
14.6/2:

A name used in a template declaration or definition and that is
dependent
on a template-parameter is assumed not to name a type unless the
applicable name lookup finds a type name or the name is qualified by the
keyword typename.

On the other hand, I don't understand the significance of type-dependent
expressions (14.6.2.2), and they're surely defined for a reason.

Yes, I probably misinterpreted 14.6.2 /1 :(

In your code dependent name could be name of type or name of value,
and construction is syntactically correct in either case.
There are several other examples

int q=0;
template<typename T> void h();
template<int I> void h();

template<typename T>
void f(){ T::f(q); }

template<typename T>
int g(){ return (T::f)-1; }

struct A {
typedef int f;
};

struct B {
static int f(int);
};

struct C {
static int const f =1;
};

template<typename T>
void e()
{
h<T::f>();
}

int main() {
f<A>();
f<B>();
g<A>();
g<C>();
e<A>();
e<C>();
}

Cheers,
Serge


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
llewelly
Guest





PostPosted: Sat Jul 03, 2004 12:03 am    Post subject: Re: Dependent names in typeid expressions Reply with quote

"Sergiy Kanilo" <skanilo (AT) artannlabs (DOT) com> writes:

Quote:
"Scott Meyers" <Usenet (AT) aristeia (DOT) com> wrote in message
news:MPG.1b4dd2218cba25ee98975f (AT) news (DOT) hevanet.com...
Dependent type names must always be preceded by "typename", right? So
consider:

template<typename T
void foo()
{
if (typeid(std::list }

gcc 3.2 issues a warning about the lack of "typename" in front of
std::list<T>::iterator, but VC7.1 and Comeau 4.3.3 accept the code without
complaint.

Como 4.3.3 at least accepts the code with typename as well as
without, so maybe with typename is more portable. :-)

Quote:
Is there something special going on here, are VC7.1 and Comeau
simply wrong, or is my understanding of typename and dependent names
wanting?

14.6.2.2
/4 Expressions of the following forms are never type-dependent
..
typeid ( expression )
typeid ( typeid )

I don't understand why this is relevant. The code GCC wants is this:

template<typename T>
void foo()
{
if (typeid(typename std::list<T>::iterator) == typeid(int));
}

Nobody is suggesting that typeid be prefixed with typename!

I look at 14.6/3, and I see:

# 3 A qualified-id that refers to a type and in which the
# nested-name-specifier depends on a template-parameter (14.6.2)
# shall be prefixed by the keyword typename to indicate that the
# qualified-id denotes a type, forming an
# elaborated-type-specifier (7.1.5.3).
#
# elaborated-type-specifier:
# ...
# typename ::opt nested-name-specifier identifier
# typename ::opt nested-name-specifier templateopt template-id

It's about whether the nested-name-specifier is type-dependent, not
about whether typeid is type-dependent.


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Michiel Salters
Guest





PostPosted: Sat Jul 03, 2004 12:03 am    Post subject: Re: Dependent names in typeid expressions Reply with quote

Scott Meyers <Usenet (AT) aristeia (DOT) com> wrote

Quote:
Dependent type names must always be preceded by "typename", right? So
consider:

template<typename T
void foo()
{
if (typeid(std::list }

gcc 3.2 issues a warning about the lack of "typename" in front of
std::list<T>::iterator, but VC7.1 and Comeau 4.3.3 accept the code without
complaint. Is there something special going on here, are VC7.1 and Comeau
simply wrong, or is my understanding of typename and dependent names
wanting?

You're making assumptions based on what you know about
std::list<T>::iterator, the compiler can't do that.

Let's write a similar example

template<typename T>
class A {
typedef T* iterator;
};
template< >
class A<void> {
static const iterator = 0;
};
template< typename T>
void foo()
{
if(typeid(A<T>::iterator) == typeid(int));
}

Should A<T>::iterator be typename A<T>::iterator instead?

Regards,
Michiel Salters

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Alberto Barbati
Guest





PostPosted: Sat Jul 03, 2004 1:23 am    Post subject: Re: Dependent names in typeid expressions Reply with quote

Sergiy Kanilo wrote:
Quote:
"Scott Meyers" <Usenet (AT) aristeia (DOT) com> wrote in message
news:MPG.1b4dd2218cba25ee98975f (AT) news (DOT) hevanet.com...

Dependent type names must always be preceded by "typename", right? So
consider:

template<typename T
void foo()
{
if (typeid(std::list }

gcc 3.2 issues a warning about the lack of "typename" in front of
std::list<T>::iterator, but VC7.1 and Comeau 4.3.3 accept the code without
complaint. Is there something special going on here, are VC7.1 and Comeau
simply wrong, or is my understanding of typename and dependent names
wanting?


14.6.2.2
/4 Expressions of the following forms are never type-dependent
..
typeid ( expression )
typeid ( typeid )
..


This is irrelevant to OP question, which relates only to the argument of
the typeid operator only, not to the entire typeid(...) expression.

The meaning of 14.6.2.2 is simply that a typeid(...) expression is never
dependent even if it may have a dependent subexpression (its argument,
in this case). That's fairly obvious because the type of the whole
expression is type_info whatever the argument is.

According to 14.6/2 and 14.6/3 the typename keyword is required, so I
believe that gcc is right and the others is wrong. Even if a compiler
adopted a relaxed parsing rule, the typename keyword cannot be avoided
in such context, as the argument of typeid is allowed to be an
expression. Consider the expression:

typeid(mytemplate<T>::mytype*)

without the typename keyword, the compiler must assume that mytype is
*not* a type and so the subsequent "*" is to be interpreted as a
multiplication operator, resulting in a syntax error because of the
missing right operand. Instead, with the typename keyword, the "*" is
interpred as part of the type-id.

Alberto

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Scott Meyers
Guest





PostPosted: Sat Jul 03, 2004 2:17 am    Post subject: Re: Dependent names in typeid expressions Reply with quote

On Sat, 3 Jul 2004 00:03:49 +0000 (UTC), Michiel Salters wrote:
Quote:
Let's write a similar example

template<typename T
class A {
typedef T* iterator;
};
template
class A static const iterator = 0;
};
template< typename T
void foo()
{
if(typeid(A }

Should A<T>::iterator be typename A<T>::iterator instead?

If, as author of foo, I believe that A<T>::iterator will be a type, yes.
If I believe that A<T>::iterator will not be a type, I should not.

I understand your point, but the whole idea behind typename is for the
author of a template to tell the compiler when something ambiguous is the
name of a type. In the particular example I posted, list<T>::iterator is
the name of a type, so my belief is that I should have to say that.

For the error to be manifest, the template must be instantiated, so
here's a complete program (less #includes):

template<typename T>
void foo()
{
if (typeid(std::list<T>::iterator) == typeid(int));
}

int main()
{
foo<int>();
}

This causes instantiation of foo<int>, which refers to
std::list<int>::iterator, which is a type. It should thus be preceded by
typename. It's not, and I believe that that is an error. As I reported
before, VC7.1 and Comeau 4.3.3 accept the code silently. Gcc 3.2 issues a
warning.

Scott

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Gabriel Dos Reis
Guest





PostPosted: Sat Jul 03, 2004 10:04 pm    Post subject: Re: Dependent names in typeid expressions Reply with quote

[email]Usenet (AT) aristeia (DOT) com[/email] (Scott Meyers) writes:

Quote:
I understand your point, but the whole idea behind typename is for the
author of a template to tell the compiler when something ambiguous is the
name of a type.

The whole idea behind "typename" is to accomodate parser internals. :-)

--
Gabriel Dos Reis
[email]gdr (AT) cs (DOT) tamu.edu[/email]
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.