| View previous topic :: View next topic |
| Author |
Message |
Avi Kak Guest
|
Posted: Sun Oct 24, 2004 10:10 am Post subject: problem with iterators in templatized functions |
|
|
I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
But now the declaration in line (A) elicits the
following error from the compiler:
error: expected init-declarator before "CI"
I am using g++ version 3.4.1. Any help with
resolving this would be much appreciated.
Avi Kak
[email]kak (AT) purdue (DOT) edu[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Mon Oct 25, 2004 1:42 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak <kak (AT) purdue (DOT) edu> writes:
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
|
Consider passing this list by reference to const to prevent it from
being
copied.
| Quote: | typedef list<T>::const_iterator CI; //(A)
|
Unless you say so, the compiler assumes const_iterator to *not* name a
type
here. You have to write
typedef typename list<T>::const_iterator CI;
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Sumit Rajan Guest
|
Posted: Mon Oct 25, 2004 4:30 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak wrote:
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
|
typedef typename list<T>::const_iterator CI;
You need to tell your compiler that list<T>::const_iterator is a type.
--
Sumit Rajan <sumit DOT rajan AT gmail DOT com>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bob Hairgrove Guest
|
Posted: Mon Oct 25, 2004 4:35 pm Post subject: Re: problem with iterators in templatized functions |
|
|
On 24 Oct 2004 06:10:54 -0400, Avi Kak <kak (AT) purdue (DOT) edu> wrote:
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
|
Since templates are usually contained totally in header files, you
should not have "using namespace std;" declared ANYWHERE in those
headers. You need to write std::list<> and not just list<>.
Try this:
typedef typename std::list<T>::const_iterator CI;
Inside template code, you must use the "typename" keyword for
templates which are dependent on the template argument.
--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Antoun Kanawati Guest
|
Posted: Mon Oct 25, 2004 4:41 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak wrote:
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
But now the declaration in line (A) elicits the
following error from the compiler:
error: expected init-declarator before "CI"
I am using g++ version 3.4.1. Any help with
resolving this would be much appreciated.
|
Nearly all of my foo
an extra 'typename' right before the typedef refrence. I am used
to a different message from g++ (3.x.y, where x <= 3), a warning
about 'implicit typename' being deprecated or obsolete. This
usually means that 'implicit typename' will soon disappear, and
an explicit typename will be required.
Since 3.4.1 > 3.3.y, I am guessing that your version has crossed
the threshold on this particular item.
The following example illustrates why list<T>::const_iterator
needs an 'typename' in front of it, in the context above.
// what is: foo<T>::type ?
template<typename S> struct foo {
// nothing!
};
template<> struct foo<unsigned int> {
typedef unsigned int type;
};
template<> struct foo<char> {
static const int type = 0xDeadBeef; // still not a type.
};
This sort of construct is commonly used to implement compile-time
assertions on type properties.
--
A. Kanawati
[email]NO.antounk.SPAM (AT) comcast (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Frank Birbacher Guest
|
Posted: Mon Oct 25, 2004 4:43 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Hi!
Avi Kak wrote:
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
|
This might help:
typedef typename list
Frank
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Rob Mayoff Guest
|
Posted: Mon Oct 25, 2004 4:47 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak <kak (AT) purdue (DOT) edu> wrote
| Quote: | typedef list<T>::const_iterator CI; //(A)
|
Try this:
typedef typename list<T>::const_iterator CI;
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alberto Barbati Guest
|
Posted: Mon Oct 25, 2004 7:51 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak wrote:
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
|
Are you sure you want to pass a list by-value??? That would make a copy
of the list and all its elements, wasting time and memory. Your function
doesn't need a copy of the list and you are not going to modify it (in
fact you are using a const_iterator), so you will be better off passing
the list by-reference, like this:
template<class T> void print( list<T> const& li ) {
| Quote: | typedef list<T>::const_iterator CI; //(A)
|
Should be:
typedef typename list<T>::const_iterator CI;
^^^^^^^^
HTH,
Alberto
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Helium Guest
|
Posted: Mon Oct 25, 2004 7:54 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak <kak (AT) purdue (DOT) edu> wrote
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
But now the declaration in line (A) elicits the
following error from the compiler:
error: expected init-declarator before "CI"
I am using g++ version 3.4.1. Any help with
resolving this would be much appreciated.
|
typedef typename list
-- Matthias
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gareth Stockwell Guest
|
Posted: Tue Oct 26, 2004 4:18 am Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak <kak (AT) purdue (DOT) edu> wrote
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
error: expected init-declarator before "CI"
|
Avi,
I think you need to qualify list
'typename' keyword in front of it.
Gareth
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Tue Oct 26, 2004 4:22 am Post subject: Re: problem with iterators in templatized functions |
|
|
On 24 Oct 2004 06:10:54 -0400, Avi Kak <kak (AT) purdue (DOT) edu> wrote:
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
But now the declaration in line (A) elicits the
following error from the compiler:
error: expected init-declarator before "CI"
|
typedef *typename* list
--
Maxim Yegorushkin
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jakacki Guest
|
Posted: Tue Oct 26, 2004 4:23 am Post subject: Re: problem with iterators in templatized functions |
|
|
| Quote: | template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
|
typedef typename list<T>::const_iterator CI;
^^^^^^^^
| Quote: | for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
|
HTH
Grzegorz
--
Free C++ frontend library: http://opencxx.sourceforge.net
China from the inside: http://www.staryhutong.com
Myself: http://www.dziupla.net/gj/cv
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gianni Mariani Guest
|
|
| Back to top |
|
 |
Michiel Salters Guest
|
Posted: Tue Oct 26, 2004 1:04 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak <kak (AT) purdue (DOT) edu> wrote
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
But now the declaration in line (A) elicits the
following error from the compiler:
error: expected init-declarator before "CI"
|
The problem is that until you know T, you won't know what
const_iterator is. In theory there could be a specialization
list
compiler will not try all list<T>'s to see what onst_iterator
can be ( list<T> is an infinite collection of classes ).
You can however assert that list<T>::const_iterator always is a type,
which satisfies your compiler. This will cause an instantiation error
if anyone does something stupid, as you'd expect. The syntax you need
is "typedef typename list<T>::const_iterator CI;"
Regards,
Michiel Salters
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jon hanson Guest
|
Posted: Tue Oct 26, 2004 1:12 pm Post subject: Re: problem with iterators in templatized functions |
|
|
Avi Kak <kak (AT) purdue (DOT) edu> wrote
| Quote: | I used to be able to define a templatized function
in the following manner
template<class T> void print( list<T> li ) {
typedef list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
But now the declaration in line (A) elicits the
following error from the compiler:
error: expected init-declarator before "CI"
I am using g++ version 3.4.1. Any help with
resolving this would be much appreciated.
|
i think you need to tell the compiler that list
in fact a type (as opposed to a member variable for instance) :-
template<class T> void print( list<T> li ) {
typedef typename list<T>::const_iterator CI; //(A)
for ( CI iter = li.begin(); iter != li.end(); iter++ )
cout << iter->name << " " << iter->age << " ";
}
Note that if you simply implement operator<<() for whatever type has
the name and age fields like the following:-
std::ostream& operator<< (std::ostream& os, const Person& person)
{
return os << person.name << ' ' << person.age;
}
then you can stream a collection of Persons with :-
std::copy (li.begin (), li.end (), std::ostream_iterator
(std::cout, " "));
where li can be vector, list, or deque, etc.
jon
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|