473,382 Members | 1,165 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Why doesn't this code compile?

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

Jul 16 '06 #1
11 1229
* 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.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 16 '06 #2
fungus wrote:
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.
Jul 16 '06 #3
James Bannon wrote:
>
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.
Jul 16 '06 #4
Pete Becker wrote:
James Bannon wrote:
>>
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.
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.
Jul 16 '06 #5
fungus wrote:
<\___/>
/ 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

--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
Jul 16 '06 #6
James Bannon wrote:
>
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

Jul 16 '06 #7
James Bannon wrote:
Pete Becker wrote:
James Bannon wrote:
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.

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.

Jul 17 '06 #8
Old Wolf wrote:
>
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

Jul 17 '06 #9
fungus wrote:
Old Wolf wrote:

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?
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).

Jul 17 '06 #10
fungus wrote:
Old Wolf wrote:
>>
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?
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<intci;

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<intrather
than when you define C.
Jul 17 '06 #11
In message <Zf******************@newsfe1-win.ntli.net>, James Bannon
<ja**********@ntlworld.comwrites
>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.
--
Richard Herring
Jul 17 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: James Thurley | last post by:
I'm trying to dynamically compile assemblies and cache them to disk, which seems to work fine. When the data I'm compiling from changes, I want to re-generate the assembly and use the new version....
4
by: Fernando Cuenca | last post by:
Hi, I'm trying to explicitly instantiate a template function using the following syntax: obj.template_func<type>(params); It compiles OK when used from a regular function, but it doesn't...
149
by: Christopher Benson-Manica | last post by:
(Followups set to comp.std.c. Apologies if the crosspost is unwelcome.) strchr() is to strrchr() as strstr() is to strrstr(), but strrstr() isn't part of the standard. Why not? --...
1
by: rvan | last post by:
Hi, I am trying to port one of my older MFC APP created in VC 6.0 to VC 7.0. Right away after starting the compile process, I get following errors and compilation stops. "d:\Microsoft .NET...
5
by: Jason Huang | last post by:
Hi, A javascript code is changed on file WebForm.aspx.cs, in my ASP.Net C#. However, it seems the MSIE doesn't repond immediately after the code updated, and it still shows me the stuff before...
4
by: Eric Lilja | last post by:
Is this an invalid program? Doesn't compile on my system: #include <cstdio> class Why { enum TArch {LITTLE_ENDIAN, BIG_ENDIAN, NON_IEEE}; TArch Architecture; }; int
10
by: Sourcerer | last post by:
I wrote this very simple code in .NET VC++. I compiled it on my system, and tried to run it on my friend's computer (he doesn't have the compiler). We both have Windows XP Professional. I have .NET...
13
by: hn.ft.pris | last post by:
Hi: I have the following simple program: #include<iostream> using namespace std; int main(int argc, char* argv){ const double L = 1.234; const int T = static_cast<const int>(L); int arr;
35
by: mwelsh1118 | last post by:
Why doesn't C# allow incremental compilation like Java? Specifically, in Java I can compile single .java files in isolation. The resulting individual .class files can be grouped into .jar files....
10
by: =?Utf-8?B?U2NvdHQgUy4=?= | last post by:
I need to have custom event subscribe and unsubscribe methods in some code in my application when I ran into this problem. I created this simple class to demostrate the compile problem. The use of...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.