Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > syntax error in std::vector<T>::const_iterator where T = (class) U<V>

Reply
Thread Tools

syntax error in std::vector<T>::const_iterator where T = (class) U<V>

 
 
m0shbear
Guest
Posts: n/a
 
      02-06-2011
With the following code, I get the following error from my compiler:
"In member function 'void B<U>::C()': error: expected ';' before 'x'".
Which subtlety of using templates am I not aware of?

#include <vector>
template <class T> struct A {};
template <class U> struct B {
void C() { std::vector<A<U> >::const_iterator x;}
};
int main(){}
 
Reply With Quote
 
 
 
 
Bo Persson
Guest
Posts: n/a
 
      02-06-2011
m0shbear wrote:
> With the following code, I get the following error from my compiler:
> "In member function 'void B<U>::C()': error: expected ';' before
> 'x'". Which subtlety of using templates am I not aware of?
>
> #include <vector>
> template <class T> struct A {};
> template <class U> struct B {
> void C() { std::vector<A<U> >::const_iterator x;}
> };
> int main(){}


That the compiler cannot formally know that
std::vector<A<U>>::const_iterator is a type (because someone could
specialize std::vector for some user defined types). You have to add a
'typename' to specify what it is:

void C() { typename std::vector<A<U> >::const_iterator x;}


Bo Persson




 
Reply With Quote
 
 
 
 
m0shbear
Guest
Posts: n/a
 
      02-06-2011
On Feb 6, 3:54*am, "Bo Persson" <b...@gmb.dk> wrote:
> m0shbear wrote:
> > With the following code, I get the following error from my compiler:
> > "In member function 'void B<U>::C()': error: expected ';' before
> > 'x'". Which subtlety of using templates am I not aware of?

>
> > #include <vector>
> > template <class T> struct A {};
> > template <class U> struct B {
> > void C() { std::vector<A<U> >::const_iterator x;}
> > };
> > int main(){}

>
> That the compiler cannot formally know that
> std::vector<A<U>>::const_iterator is a type (because someone could
> specialize std::vector for some user defined types). You have to add a
> 'typename' to specify what it is:
>
> *void C() { typename std::vector<A<U> >::const_iterator x;}
>
> Bo Persson


Ah, now I understand the point of typename for disambiguating types. I
need to start reading TC++PL more religiously. In its listing of
vector, it had "typedef _typename_ ..." for a reason. And now I
understand what it is.

I'm curious as to why it's not in the C++ FAQ yet.
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      02-07-2011
Bo Persson <> wrote:
> That the compiler cannot formally know that
> std::vector<A<U>>::const_iterator is a type (because someone could
> specialize std::vector for some user defined types). You have to add a
> 'typename' to specify what it is:


Is there any conrete example where the same dependent name could be
used as both a type name and a non-type name, and this could potentially
cause confusion? Why exactly is the 'typename' keyword necessary?
 
Reply With Quote
 
Johannes Schaub (litb)
Guest
Posts: n/a
 
      02-07-2011
m0shbear wrote:

> With the following code, I get the following error from my compiler:
> "In member function 'void B<U>::C()': error: expected ';' before 'x'".
> Which subtlety of using templates am I not aware of?
>
> #include <vector>
> template <class T> struct A {};
> template <class U> struct B {
> void C() { std::vector<A<U> >::const_iterator x;}
> };
> int main(){}


For the typename FAQ see http://stackoverflow.com/questions/610245/where-to-
put-the-template-and-typename-on-dependent-names
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      02-07-2011
Juha Nieminen wrote:
> Bo Persson <> wrote:
>> That the compiler cannot formally know that
>> std::vector<A<U>>::const_iterator is a type (because someone could
>> specialize std::vector for some user defined types). You have to
>> add a 'typename' to specify what it is:

>
> Is there any conrete example where the same dependent name could be
> used as both a type name and a non-type name, and this could
> potentially cause confusion? Why exactly is the 'typename' keyword
> necessary?


Yes, if you specialize a class there is no requirements that the base
template and the specialization should have anything in common (except
their names .


template<class T>
class vec
{
public:
class const_iterator
{
public:
// some members here
};
};

template<>
class vec<int>
{
public:
double const_iterator; // silly, but possible
};


Now, what is vec<T>::const_iterator, a type or a member variable?
Depends on what T is!


Bo Persson


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-08-2011
On Feb 7, 5:12 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Bo Persson <b...@gmb.dk> wrote:
> > That the compiler cannot formally know that
> > std::vector<A<U>>::const_iterator is a type (because someone could
> > specialize std::vector for some user defined types). You have to add a
> > 'typename' to specify what it is:


> Is there any conrete example where the same dependent name could be
> used as both a type name and a non-type name, and this could potentially
> cause confusion? Why exactly is the 'typename' keyword necessary?


extern int p;
template<typename T>
struct S : B<T>
{
B<T>: * p; // marked statement
};

If B<T>: is the name of a type, the marked statement is a
declaration of a pointer to that type. If it is the name of a
constant or a variable, the marked statement is an expression
statement, and the * is multiplication.

In a lot of cases, context would allow the compiler to make it
clear: only a type is legal, or a type is not legal, but the
committee decided to not require the compiler to take any
context into consideration.

--
James Kanze
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      02-08-2011
Bo Persson <> wrote:
> Juha Nieminen wrote:
>> Bo Persson <> wrote:
>>> That the compiler cannot formally know that
>>> std::vector<A<U>>::const_iterator is a type (because someone could
>>> specialize std::vector for some user defined types). You have to
>>> add a 'typename' to specify what it is:

>>
>> Is there any conrete example where the same dependent name could be
>> used as both a type name and a non-type name, and this could
>> potentially cause confusion? Why exactly is the 'typename' keyword
>> necessary?

>
> Yes, if you specialize a class there is no requirements that the base
> template and the specialization should have anything in common (except
> their names .


In your example if you try to use the specialization in code where
'const_iterator' is expected to be a type, you get a syntax error. In
the exact same way as if that 'typename' keyword had been specified.
So what's the difference?

That's not what I asked. I asked if there's a situation where you *don't*
get a syntax error, but it compiles fine but causes unwanted behavior.
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      02-08-2011
James Kanze <> wrote:
> In a lot of cases, context would allow the compiler to make it
> clear: only a type is legal, or a type is not legal, but the
> committee decided to not require the compiler to take any
> context into consideration.


The following doesn't compile. Why shouldn't it? I see no rational
reason why the compiler should refuse to compile it.

//---------------------------------------------------------------
#include <iostream>

template<typename T>
void foo()
{
T::f(); // Is 'f' a function or a type?
}

struct A
{
// 'f' is a function
static void f() { std::cout << "A\n"; }
};

struct B
{
// 'f' is a type
struct f
{
f() { std::cout << "B\n"; }
};
};

int main()
{
foo<A>();
foo<B>(); // Fails because B::f is a type
}
//---------------------------------------------------------------
 
Reply With Quote
 
Paul
Guest
Posts: n/a
 
      02-08-2011

"Juha Nieminen" <> wrote in message
news:4d50e156$0$2819$...
> James Kanze <> wrote:
>> In a lot of cases, context would allow the compiler to make it
>> clear: only a type is legal, or a type is not legal, but the
>> committee decided to not require the compiler to take any
>> context into consideration.

>
> The following doesn't compile. Why shouldn't it? I see no rational
> reason why the compiler should refuse to compile it.
>
> //---------------------------------------------------------------
> #include <iostream>
>
> template<typename T>
> void foo()
> {
> T::f(); // Is 'f' a function or a type?
> }
>
> struct A
> {
> // 'f' is a function
> static void f() { std::cout << "A\n"; }
> };
>
> struct B
> {
> // 'f' is a type
> struct f
> {
> f() { std::cout << "B\n"; }


Where is this function declared?

> };
> };
>
> int main()
> {
> foo<A>();
> foo<B>(); // Fails because B::f is a type
> }
> //---------------------------------------------------------------
>


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Syntax error? What syntax error? Assignment fo default values? Mark Richards Perl Misc 3 11-18-2007 05:01 PM
Syntax bug, in 1.8.5? return not (some expr) <-- syntax error vsreturn (not (some expr)) <-- fine Good Night Moon Ruby 9 07-25-2007 04:51 PM
[ANN] SqlStatement 1.0.0 - hide the syntax of SQL behind familiarruby syntax Ken Bloom Ruby 3 10-09-2006 06:46 PM
Syntax highligth with textile: Syntax+RedCloth ? gabriele renzi Ruby 2 12-31-2005 02:44 AM
Complier error!! error C2059: syntax error : '(' Balaji C++ 3 12-03-2004 11:19 PM



Advertisments