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 

No typename needed before std::list<T>?
Goto page 1, 2  Next
 
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: Sat Jan 29, 2005 6:31 am    Post subject: No typename needed before std::list<T>? Reply with quote



I thought I understood the rules regarding typename, but it seems I was
mistaken. I was under the impression that anytime you refer to a dependent
type name in a template, you had to qualify it with typename. But consider
this:

template<typename T>
class Widget {
typedef typename std::list<T> CollectionType1; // 1
typedef std::set<T> CollectionType2; // 2
};

My expectation was that 1 would compile, but 2 would not. But the three
compilers I have here all accept both. Sigh. Why doesn't 2 require a
typename?

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
Nicolas Pavlidis
Guest





PostPosted: Sat Jan 29, 2005 2:14 pm    Post subject: Re: No typename needed before std::list<T>? Reply with quote



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

Quote:
I thought I understood the rules regarding typename, but it seems I was
mistaken. I was under the impression that anytime you refer to a dependent
type name in a template, you had to qualify it with typename. But consider
this:

template<typename T
class Widget {
typedef typename std::list typedef std::set<T> CollectionType2; // 2
};

I always thought that only nested types have to be qualified with
typename:

template<typename Type>
class Test
{
public:
typedef std::list<Type> TypeList; // Smile
typedef typename std::list<Type>::iterator TypeListIterator;
};

If I remove the typename of the second typedef I'll get a warning under
gcc 3.3 and an errormessage under gcc 3.4.

I'm far away from beeing an expert so I have no good explanation for
this, but maybe it's becaue Templatets can be instantiated with
incomplete types, and so the line marked with the smily wokrs, but the
other line does not, because std::list<Type> is no complete type at this
moment, but it can be nonsense too Smile.

Best regards,
Nicolas

--
Quote:
Nicolas Pavlidis | Elvis Presly: | |__ |
Student of SE & KM | "Into the goto" | |__| |
[email]pavnic (AT) sbox (DOT) tugraz.at[/email] | ICQ #320057056 | |
-------------------University of Technology, Graz----------------|

---
[ 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
Michael Pryhodko
Guest





PostPosted: Sat Jan 29, 2005 2:14 pm    Post subject: Re: No typename needed before std::list<T>? Reply with quote



Quote:
template<typename T
class Widget {
typedef typename std::list typedef std::set<T> CollectionType2; // 2
};

My expectation was that 1 would compile, but 2 would not. But the
three
compilers I have here all accept both. Sigh. Why doesn't 2 require
a
typename?

14.6.p2... read twice Smile (there is barely visible 'OR')
Bye.
Sincerely yours, Michael.

---
[ 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 B. Held
Guest





PostPosted: Sat Jan 29, 2005 4:17 pm    Post subject: Re: No typename needed before std::list<T>? Reply with quote

Scott Meyers wrote:
Quote:
I thought I understood the rules regarding typename, but it seems I was
mistaken. I was under the impression that anytime you refer to a dependent
type name in a template, you had to qualify it with typename. But consider
this:

template<typename T
class Widget {
typedef typename std::list typedef std::set<T> CollectionType2; // 2
};

My expectation was that 1 would compile, but 2 would not. But the three
compilers I have here all accept both. Sigh. Why doesn't 2 require a
typename?

Neither of them do. The compiler already knows that std::list is a
parameterized type. Once you supply a parameter (formal or otherwise),
it, becomes a concrete (typedefable) type. You cannot substitute any
value for T to make std::list<T> anything but a type (say, a value).
On the other hand, the same is not true for std::list<T>::iterator.
Suppose, for the sake of argument, that I perversely defined
std::list<T>::iterator like so:

template <typename T>
struct list
{
typedef T* iterator;
};

template <>
struct list<int>
{
static int const iterator = 42;
};

This is not only perfectly confusing, it's perfectly legal. Now,
does std::list<T>::iterator refer to a type or a value? Without
knowing what T is, you can't say, can you? In order to write
template types that assume one way or the other, you have to give
the compiler a hint as to which one you are writing for. That's
why iterator is a dependent type, and that's why it needs a
typename.

Dave

---
[ 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
Bo Persson
Guest





PostPosted: Sat Jan 29, 2005 6:00 pm    Post subject: Re: No typename needed before std::list<T>? Reply with quote


"Scott Meyers" <Usenet (AT) aristeia (DOT) com> skrev i meddelandet
news:MPG.1c64b696d96bc439897b1 (AT) news (DOT) hevanet.com...
Quote:
I thought I understood the rules regarding typename, but it seems I was
mistaken. I was under the impression that anytime you refer to a
dependent
type name in a template, you had to qualify it with typename. But
consider
this:

template<typename T
class Widget {
typedef typename std::list typedef std::set<T> CollectionType2; // 2
};

My expectation was that 1 would compile, but 2 would not. But the
three
compilers I have here all accept both. Sigh. Why doesn't 2 require a
typename?


Because std::set is known to be a type, for all T's. So is std::list, so
the typename in 1 isn't needed either.

The problem of deciding what is type comes up when the types are nested.
You could have a specialization, like

template<>
class std::set<some_type>
{
int iterator;
};


typedef typename std::set<T>::iterator iterator_type;


Here you really need typename to indicate that you want the typedef to
work for the cases where iterator really *is* a type, and not for the
cases where it might be something else, like a variable.

For typedefs the compiler might be intelligent enough to expect types
anyway, but for an expression like

typename std::set<T>::value_type * x;

it is impossible to determine if it is a pointer declaration or a
multiplication, unless you know what names are supposed to be types.


Bo Persson





---
[ 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: Sat Jan 29, 2005 9:59 pm    Post subject: Re: No typename needed before std::list<T>? Reply with quote

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

Quote:
I thought I understood the rules regarding typename, but it seems I was
mistaken. I was under the impression that anytime you refer to a dependent
type name in a template, you had to qualify it with typename. But consider
this:

template<typename T
class Widget {
typedef typename std::list typedef std::set<T> CollectionType2; // 2
};

My expectation was that 1 would compile, but 2 would not. But the three
compilers I have here all accept both. Sigh. Why doesn't 2 require a
typename?

First of all, since I know you have it, check out Appendix B of
http://boost-consulting.com/metaprogramming-book.html. I think we've
got the most complete explanation going right now. It lays out all
the groundwork for understanding this.

The compiler needs typename to help it distinguish when a name refers
to a type. You can't even compile

typedef std::set<T> CollectionType2;

unless the compiler has seen a declaration for std::set<T>, and
nothing you can do with specializations or otherwise will change the
fact that std::set is a class template and std::set<T> is a type.

The reason the compiler needs to see typename in

typedef typename std::set<T>::iterator iterator2;

is twofold: first, you might not have shown it the primary template
definition for std::set; that line should compile even after only
seeing

namespace std {
template <class T, class A> class set;
}

Second, whether std::set<T>::iterator is a type could depend on the
actual T you are passed. For example,

template <class T>
struct set<T*>
{
enum { iterator };
}

Whoops; set<T*>::iterator is not a type.

HTH,

--
Dave Abrahams
Boost Consulting
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
Scott Meyers
Guest





PostPosted: Sun Jan 30, 2005 1:44 am    Post subject: Re: No typename needed before std::list<T>? Reply with quote

On Sat, 29 Jan 2005 21:59:13 GMT, David Abrahams wrote:
Quote:
First of all, since I know you have it, check out Appendix B of
http://boost-consulting.com/metaprogramming-book.html. I think we've
got the most complete explanation going right now. It lays out all
the groundwork for understanding this.

It's nice, but it has the disadvantage of defining "dependent name" in a
way I find hard to understand, much less explain. As the author of source
code, how am I to know when the "syntactic role" played by an identifier
depends on what type a type parameter turns out to be? Section 9.3.2 of
Vandevoorde and Josuttis is more precise, but it requires that I understand
what a qualified name is, and I find that hard to do, even though they do
their best to define it in table 9.2. Further complicating matters is the
Standard, which, as is often the case regarding templates, is essentially
impossible to understand. IMO.

Anyway, I do understand why typename is needed to disambiguate the meaning
of nested typedefs in dependent type names (e.g, Foo<T>::Widget). And I
guess I understand that compilers can tell whether Foo<T> is a type for any
template Foo and type T, so there's no need for typename in that case.

I still think it would be easier to understand and explain if the rule were
that all dependent type names must be preceded by typename, but I now
understand that that's not the rule, and I thank everybody who contributed
to my new understanding of the situation.

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
google@vandevoorde.com
Guest





PostPosted: Mon Jan 31, 2005 2:07 am    Post subject: Re: No typename needed before std::list<T>? Reply with quote


Scott Meyers wrote:
[...]
Quote:
I still think it would be easier to understand and explain if the
rule were
that all dependent type names must be preceded by typename, but I now
understand that that's not the rule, and I thank everybody who
contributed
to my new understanding of the situation.

I think I agree the "rules" are a bit too complicated right now.
More precisely, I think it's okay for the rules to be complicated,
but you should be able to get away with a simple "rule of thumb"
(which may not be optimal in terms of amount of source code,
but which doesn't requiring "trying out the various combinations
until the compiler eats it").

The Core Working Group has been working both on allowing the
"typename" disambiguator in more places, and on requiring it in
fewer places (both of those are good trends IMO).

Oh, and here is another "interesting" illustration of the current
rules; this is a test for the compiler's understanding of so-called
"injected class names":

struct N {
typedef char C;
};

template<typename> struct B {
typedef long L;
};

template<typename T> struct S: N, B<T> {
typedef int I;
S<T>::I i; // Okay
S<T>::C c; // Okay
S::L l; // Error: typename required
};

(Sorry, I cannot resist ;-)

Daveed

---
[ 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: Mon Jan 31, 2005 2:07 am    Post subject: Re: No typename needed before std::list<T>? Reply with quote

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

Quote:
On Sat, 29 Jan 2005 21:59:13 GMT, David Abrahams wrote:
First of all, since I know you have it, check out Appendix B of
http://boost-consulting.com/metaprogramming-book.html. I think we've
got the most complete explanation going right now. It lays out all
the groundwork for understanding this.

It's nice, but it has the disadvantage of defining "dependent name" in a
way I find hard to understand, much less explain. As the author of source
code, how am I to know when the "syntactic role" played by an identifier
depends on what type a type parameter turns out to be?

That description is not meant to be a definition; it's designed to
give "a feel" for what's going on. The precise rules are in section
B.2.

Quote:
Section 9.3.2 of Vandevoorde and Josuttis is more precise

Did you stop reading before you got to Section B.2?

--
Dave Abrahams
Boost Consulting
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
Gianni Mariani
Guest





PostPosted: Mon Jan 31, 2005 6:25 am    Post subject: Re: No typename needed before std::list<T>? Reply with quote

[email]google (AT) vandevoorde (DOT) com[/email] wrote:
....
Quote:

Oh, and here is another "interesting" illustration of the current
rules; this is a test for the compiler's understanding of so-called
"injected class names":

struct N {
typedef char C;
};

template<typename> struct B {
typedef long L;
};

template<typename T> struct S: N, B<T> {
typedef int I;
S<T>::I i; // Okay
S<T>::C c; // Okay
S::L l; // Error: typename required
};

Are you sure ?

gcc (GCC) 4.0.0 20050102 (experimental) says:

typename_nonsense.cpp:11: error: expected ‘;’ before ‘i’
typename_nonsense.cpp:12: error: expected ‘;’ before ‘c’
typename_nonsense.cpp:13: error: expected ‘;’ before ‘l’

Similar errors from MSVC++ 2003.

Although http://www.comeaucomputing.com/tryitout does seem to agree with
you.

g++ (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5) also seems to agree
with you.

What a mess...

---
[ 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
Ben Hutchings
Guest





PostPosted: Mon Jan 31, 2005 6:22 pm    Post subject: Re: No typename needed before std::list<T>? Reply with quote

Gianni Mariani wrote:
Quote:
google (AT) vandevoorde (DOT) com wrote:
...

Oh, and here is another "interesting" illustration of the current
rules; this is a test for the compiler's understanding of so-called
"injected class names":

struct N {
typedef char C;
};

template<typename> struct B {
typedef long L;
};

template<typename T> struct S: N, B<T> {
typedef int I;
S<T>::I i; // Okay
S<T>::C c; // Okay
S::L l; // Error: typename required

Presumably most compilers will treat at least S<T> as dependent,
whereas S<T> and S should logically be treated as locally declared and
therefore non-dependent?

Quote:
};

Are you sure ?

gcc (GCC) 4.0.0 20050102 (experimental) says:

typename_nonsense.cpp:11: error: expected ?;? before ?i?
typename_nonsense.cpp:12: error: expected ?;? before ?c?
typename_nonsense.cpp:13: error: expected ?;? before ?l?

Similar errors from MSVC++ 2003.

This is not terribly surprising, as I think the code is ill-formed
according to the current standard. But see
<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#224>.

Quote:
Although http://www.comeaucomputing.com/tryitout does seem to agree with
you.

Given that David works on the front-end used by the Comeau compiler,
that's not surprising.

Quote:
g++ (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5) also seems to agree
with you.

It doesn't implement two-phase name resolution.

Quote:
What a mess...

--
Ben Hutchings
Larkinson's Law: All laws are basically false.

---
[ 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
google@vandevoorde.com
Guest





PostPosted: Mon Jan 31, 2005 6:23 pm    Post subject: Re: No typename needed before std::list<T>? Reply with quote


Gianni Mariani wrote:
Quote:
google (AT) vandevoorde (DOT) com wrote:
...

Oh, and here is another "interesting" illustration of the current
rules; this is a test for the compiler's understanding of so-called
"injected class names":

struct N {
typedef char C;
};

template<typename> struct B {
typedef long L;
};

template<typename T> struct S: N, B<T> {
typedef int I;
S<T>::I i; // Okay
S<T>::C c; // Okay
S::L l; // Error: typename required
};

Are you sure ?

Yes. It's a consequence of the resolution of core issue 224
(which improves the definition of "dependent type").

Daveed

---
[ 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
Jonathan Turkanis
Guest





PostPosted: Tue Feb 01, 2005 3:18 am    Post subject: Re: No typename needed before std::list<T>? Reply with quote

Gianni Mariani wrote:
Quote:
google (AT) vandevoorde (DOT) com wrote:

Oh, and here is another "interesting" illustration of the current
rules; this is a test for the compiler's understanding of so-called
"injected class names":

struct N {
typedef char C;
};

template<typename> struct B {
typedef long L;
};

template<typename T> struct S: N, B<T> {
typedef int I;
S<T>::I i; // Okay
S<T>::C c; // Okay
S::L l; // Error: typename required
};

Are you sure ?

Although http://www.comeaucomputing.com/tryitout does seem to agree
with you.

I 'm not sure this is entirely a coincidence ;-)

Jonathan


---
[ 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
msalters
Guest





PostPosted: Tue Feb 01, 2005 3:18 am    Post subject: Re: No typename needed before std::list<T>? Reply with quote


Gianni Mariani wrote:
Quote:
google (AT) vandevoorde (DOT) com wrote:
...

Oh, and here is another "interesting" illustration of the current
rules; this is a test for the compiler's understanding of so-called
"injected class names":

struct N {
typedef char C;
};

template<typename> struct B {
typedef long L;
};

template<typename T> struct S: N, B<T> {
typedef int I;
S<T>::I i; // Okay
S<T>::C c; // Okay
S::L l; // Error: typename required
};

Are you sure ?

gcc (GCC) 4.0.0 20050102 (experimental) says:

typename_nonsense.cpp:11: error: expected ';' before 'i'
typename_nonsense.cpp:12: error: expected ';' before 'c'
typename_nonsense.cpp:13: error: expected ';' before 'l'

Similar errors from MSVC++ 2003.

Although http://www.comeaucomputing.com/tryitout does seem to agree
with
you.

If you know how Comeau works, and where Daveed works, that's not a
very big surprise ;)

Quote:
g++ (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5) also seems to agree
with you.

What a mess...

Yep. It's complicated.
/Without/ looking at the standard, I'd say the difference is that
S names both a class and a template inside the definition of S. The
form S<T>::I refers to the current class, but the explicit use of T
defers name lookup to instantiation.

In the form S::L, the name L is not looked up in a base class during
the first phase, yet without lookup it's not known whether it names
a type.

i.e. the typename rules differ between the two phases of name lookup
in templates.

Looking at WP1655 (draft standard),
the relevant wording does appear to be similar:
S is indeed "injected" (9) which means it names both the class and
the template (which is why you can write both S and S<T>). However,
they are equivalent.

However, the injected name (S) is just as dependent as the form
S<T> (which is obviously dependent). Both name the "current
instantiation". Hence, S::C and S<T>::C are also equivalent
( but S::I is not equivalent with S::L).

14.6/3 explains when typename is required: "A qualified-id that
refers to a type and in which the nested-name-specifier depends
on a template-parameter (14.6.2) but does not refer to a member
of the current instantiation (14.6.2.1) shall be prefixed by
the keyword typename"

Now, both S::I and S::L are qualified-id's which do depend on
<T>. So, is there anything special about the "member of the
current instantiation" term? It's defined in 14.6.2.1. Both
S::I and S::L are members of the current instantiation (and
so is S::X, even though there's no X in S - yet).

So, in the current draft neither form requires typename. I'd
expect gcc 4 to follow the current draft.

HTH,
Michiel Salters

NB. "Unqualified name" is a rather important term, but it's not
formally defined. Is this a Defect? Or is it just any name that's
not a qualified name? That leaves us with the question, what's
a "Qualified name"? Obviously, there's a close relation to
qualified-id's and unqualified-id's, as defined in 5.1

---
[ 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: Tue Feb 01, 2005 4:42 am    Post subject: Re: No typename needed before std::list<T>? Reply with quote

On Mon, 31 Jan 2005 02:07:44 GMT, David Abrahams wrote:
Quote:
Did you stop reading before you got to Section B.2?

Actually, yes. You guys moved on to a new topic ("Problem Two"), so I
thought you were done with the old topic ("Problem One"). Silly somebody.
Maybe me. Maybe you. Maybe both of us. I'm not sure. Anyway, B.2 does
offer a much more detailed blow by blow of the situation.

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
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.