Why doesn't this code compile?

F

fungus

template <class T>
void foo(std::vector<T>& v)
{
std::vector<T>::iterator i = v.begin();
}

This code compiles under Visual C++ 6 but not with
g++ under Linux. Anybody know why?



The message is:

error: expected `;' before ‘i’



--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address
 
A

Alf P. Steinbach

* fungus:
template <class T>
void foo(std::vector<T>& v)
{
std::vector<T>::iterator i = v.begin();
}

This code compiles under Visual C++ 6 but not with
g++ under Linux. Anybody know why?



The message is:

error: expected `;' before ‘i’

Why don't you add 'typename'. Please check the FAQ. If this isn't
already a FAQ, please send a mail to Marshall Cline about it.

Thanks.
 
J

James Bannon

fungus said:
template <class T>
void foo(std::vector<T>& v)
{
std::vector<T>::iterator i = v.begin();
}

This code compiles under Visual C++ 6 but not with
g++ under Linux. Anybody know why?



The message is:

error: expected `;' before ‘i’

Just to amplify Alf's remark, my understanding is that this is not legal
since std::vector<T>::iterator is a dependent type (i.e., a type whose
actual "value" depends on a type parameter). I think the line should read:

typename std::vector<T>::iterator i = v.begin ();

or (better because it uses RAII)

typename std::vector<T>::iterator i(v.begin ());

P.S. Don't rely on a compiler to tell you whether or not some construct
is legal C++ - many of them haven't caught up with the Standard yet.

Cheers
Jim.
 
P

Pete Becker

James said:
Just to amplify Alf's remark, my understanding is that this is not legal
since std::vector<T>::iterator is a dependent type (i.e., a type whose
actual "value" depends on a type parameter).

Just a bit of further amplification: it's a dependent name, not a
dependent type. The meaning of the name (including whether it names a
type or something else) depends on the definition of vector<T>, which,
as you suggest, depends on the actual type of T, so can't be determined
from looking only at the template definition.
 
J

James Bannon

Pete said:
Just a bit of further amplification: it's a dependent name, not a
dependent type. The meaning of the name (including whether it names a
type or something else) depends on the definition of vector<T>, which,
as you suggest, depends on the actual type of T, so can't be determined
from looking only at the template definition.

Thanks for the clarification Pete. I'll remember that. Presumably this
wording is used because not all template parameter names are actually types?

Cheers
Jim.
 
P

Phlip

fungus said:
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

You cannot use logic to talk someone out of a position that they did not use
logic to embrace.

- apocryphally attributed to my mom
 
F

fungus

James said:
> typename std::vector<T>::iterator i = v.begin ();

Ok, that works, thanks.

I'm not sure this is covered in the FAQ. I haven't
read the FAQ for a while. There's some new stuff
in there about dependent types/names but I don't
think this particular question is answered there.


--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address
 
O

Old Wolf

James said:
Thanks for the clarification Pete. I'll remember that. Presumably this
wording is used because not all template parameter names are actually types?

The phrase "dependent name" refers to "iterator" (not T).
The meaning of the name "iterator" depends on T.

It could either be a typename, or the name of a variable; we
don't know yet. In fact, the original compiler error is because
the compiler assumes that it is the name of a variable, unless
it's instructed otherwise.
 
F

fungus

Old said:
The phrase "dependent name" refers to "iterator" (not T).
The meaning of the name "iterator" depends on T.

It could either be a typename, or the name of a variable; we
don't know yet.

Shouldn't the compiler be able to deduce that?




--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address
 
O

Old Wolf

fungus said:
Shouldn't the compiler be able to deduce that?

I think the language is designed so that the compiler can
parse a template and generate an abstract syntax tree,
without yet knowing what the template parameters are.

In other words, it shouldn't have to re-process the whole
template each time it's instantiated with new types.

This is essential for 'export' templates.

Knowledge of whether it is a typename or not is essential
for accurately parsing the file, eg:

foo<T>::bar(3)

has rather different meaning if 'bar' is a static function,
than if 'bar' is a typename. (Note, my description is
undoubtedly inaccurate in the detail, but this is the
general idea).
 
P

Pete Becker

fungus said:
Shouldn't the compiler be able to deduce that?

Not at the point where the template is defined, which is where you want
to do early syntax checking.

template <class Ty>
struct S
{
typedef int MyType;
};

int i = 3;

template <class Ty>
struct C
{
S<Ty>::MyType * i; // declaration of variable, or multiplication?
};

If S<Ty>::MyType names a type, then the marked statement defines a data
member named i. If it names a value, then the marked statement
multiplies two numbers and throws the result away (assuming operator*
isn't overloaded). At this point in the source code it looks like MyType
names a type, but wait:

template <> struct S<int>
{
int i;
};

C<int> ci;

This uses the specialization S<int>, and now the expression means
something completely different.

Using typename in the definition of C is required so that the compiler
can analyze the syntax of that definition at the point where it occurs.
Without that, i.e. if the compiler assumes that S<Ty>::MyType always
names a type, you get error messages when you try to use C<int> rather
than when you define C.
 
R

Richard Herring

James Bannon said:
I think the line should read:

typename std::vector<T>::iterator i = v.begin ();

or (better because it uses RAII)

typename std::vector<T>::iterator i(v.begin ());

???

Those are equivalent, and there's no resource allocation anywhere in
sight.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top