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>

 
 
James Kanze
Guest
Posts: n/a
 
      02-08-2011
On Feb 8, 6:23 am, Juha Nieminen <(E-Mail Removed)> wrote:
> James Kanze <(E-Mail Removed)> 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.


Because the standard says that it shouldn't compile. You've
presented an interesting question, however...

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


What's interesting here is that the syntax is remarkably similar
in both cases. Formally, if f is a function, this line is
a function call; if it's a type, the line is an "explicit type
conversion (funtional notation)". But unlike a lot of the other
cases, it's easy to imagine an implementation which doesn't
really distinguish between the two until far later. The choice,
here, can't have any impact on later code.

Still, the standard says that when parsing the template, the
compiler is required to assume that f is not 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}
> //---------------------------------------------------------------


That's what the standard requires.

I don't see why the compiler couldn't defer the decision in this
case; I suppose that the only reason it doesn't is to be
orthogonal with cases where it must know.

--
James Kanze
 
Reply With Quote
 
 
 
 
Paul
Guest
Posts: n/a
 
      02-08-2011

"James Kanze" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On Feb 8, 6:23 am, Juha Nieminen <(E-Mail Removed)> wrote:
>> James Kanze <(E-Mail Removed)> 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.

>
> Because the standard says that it shouldn't compile. You've
> presented an interesting question, however...
>
>> //---------------------------------------------------------------
>> #include <iostream>
>>
>> template<typename T>
>> void foo()
>> {
>> T::f(); // Is 'f' a function or a type?

>
> What's interesting here is that the syntax is remarkably similar
> in both cases. Formally, if f is a function, this line is
> a function call; if it's a type, the line is an "explicit type
> conversion (funtional notation)". But unlike a lot of the other
> cases, it's easy to imagine an implementation which doesn't
> really distinguish between the two until far later. The choice,
> here, can't have any impact on later code.
>
> Still, the standard says that when parsing the template, the
> compiler is required to assume that f is not 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}
>> //---------------------------------------------------------------

>
> That's what the standard requires.
>
> I don't see why the compiler couldn't defer the decision in this
> case; I suppose that the only reason it doesn't is to be
> orthogonal with cases where it must know.
>
> --


This doesn't happen on my compiler. MS 32-bit optimising compiler version
14.00......
Here is my source code:

#include <iostream>
struct A{static void bar(){std::cout<<"A function.";}
};
struct B{
struct bar{ bar(){std::cout<<"In constructor.";} };
};

template<typename T>void foo() { T::bar();}

int main(){
foo<B>();
foo<A>();
}

// Output = In constructor.A function.





 
Reply With Quote
 
 
 
 
Robert Hairgrove
Guest
Posts: n/a
 
      02-08-2011
On 02/08/2011 07:23 AM, Juha Nieminen wrote:
> James Kanze<(E-Mail Removed)> 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?
> }
>


If T::f(); were a function, it would have to return something (either
void, or a pointer, reference or object of some type). Since the class
name is "foo", it can't be parsed as a constructor. So it shouldn't
compile in any case, even lacking the "typename" keyword.

If you had written "T::foo();" instead, no typename would be needed
since this would obviously be the declaration of a class constructor (at
least I don't think it could be interpreted any other way).
 
Reply With Quote
 
Robert Hairgrove
Guest
Posts: n/a
 
      02-08-2011
On 02/08/2011 06:31 PM, Robert Hairgrove wrote:

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

>
> If T::f(); were a function, it would have to return something (either
> void, or a pointer, reference or object of some type). Since the class
> name is "foo", it can't be parsed as a constructor. So it shouldn't
> compile in any case, even lacking the "typename" keyword.


Oops ... I overlooked the fact that this is a function template, not a
class template.

So the compiler should look for a member function of T called f()
returning void. 'f' could not be a type (nor could T::f).
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      02-08-2011
Juha Nieminen wrote:
> Bo Persson <(E-Mail Removed)> wrote:
>> Juha Nieminen wrote:
>>> Bo Persson <(E-Mail Removed)> 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?


The difference is that the compiler should be allowed to diagnose
template code before it is instantiated. If you don't know whether a
name is a type or not, a lot of code turns out to be impossible to
interpret. For example, is "a * b" a pointer declaration or a
multiplication? If I use b later on in the class, am I then using this
pointer or some b from an outer scope?

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


It isn't allowed to do that. A name must either be a type or not. If
the compiler can't tell, it must assume that it is not.


Bo Persson


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-09-2011
On Feb 8, 12:38 pm, "Paul" <(E-Mail Removed)> wrote:
> "James Kanze" <(E-Mail Removed)> wrote in message


> news:(E-Mail Removed)...


[...]
> >> 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}
> >> //---------------------------------------------------------------


> > That's what the standard requires.


> > I don't see why the compiler couldn't defer the decision in this
> > case; I suppose that the only reason it doesn't is to be
> > orthogonal with cases where it must know.


> This doesn't happen on my compiler. MS 32-bit optimising compiler version
> 14.00......


Not all compilers are up to date concerning this. A lot
(included VC++ through 2005, at least) continue to defer all
template parsing until instantiation, at which point in time,
the meaning of f is unambiguously known. Implementing the
latest rules for name lookup in templates (aka breaking existing
code) isn't always the highest priority of compiler writers.

--
James Kanze
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      02-10-2011
Paul <(E-Mail Removed)> wrote:
>> struct B
>> {
>> // 'f' is a type
>> struct f
>> {
>> f() { std::cout << "B\n"; }

>
> Where is this function declared?


It's a constructor.
 
Reply With Quote
 
Paul
Guest
Posts: n/a
 
      02-10-2011

"Juha Nieminen" <(E-Mail Removed)> wrote in message
news:4d5423b7$0$2853$(E-Mail Removed)...
> Paul <(E-Mail Removed)> wrote:
>>> struct B
>>> {
>>> // 'f' is a type
>>> struct f
>>> {
>>> f() { std::cout << "B\n"; }

>>
>> Where is this function declared?

>
> It's a constructor.
>

My bad, I misread it. No problem I seen it after I posted.

 
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