Topic: BUG or Feature : Where starts the scope of a class template ?
Author: Martin.Cornelius@t-online.de (Martin Cornelius)
Date: Sun, 18 Jan 2004 18:14:34 +0000 (UTC) Raw View
Having started to work through A. Alexandrescu's great 'Modern C++ Design'
book, i encountered the following problem:
This template definition is invalid with g++ 3.3.2
template < class T >
class A { /*...*/ };
template < class T >
class B : public A < B > { /*...*/ }
g++ rejects this with an error:
policy.cpp:8: error: type/value mismatch at argument 1 in template parameter
list for `template<class T> class A'
policy.cpp:8: error: expected a type, got `B'
policy.cpp:8: error: invalid base-class specification
In contrast, the follwowing works:
template < class T >
class B : public A < B <T> >
^^^^^
Obviously g++ does not recognize the reference to B as a type, unless it is
explicitely specialized with the template parameter as B<T>
The standard states:
14.6.1 Locally declared names
1 Within the scope of a class template, when the name of the template is
neither qualified nor followed by <,
it is equivalent to the name of the template followed by the template
parameters enclosed in <>.
Thus, i'm asking: WHERE does the 'scope of a class template' start ? Is it
just after the name has been mentioned - in this case g++ has a bug, or is
it after the opening brace - in this case g++ behaves correctly.
BTW, VC7 accepts both definitions.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jdennett@acm.org (James Dennett)
Date: Mon, 19 Jan 2004 01:10:05 +0000 (UTC) Raw View
Martin Cornelius wrote:
> Having started to work through A. Alexandrescu's great 'Modern C++ Design'
> book, i encountered the following problem:
>
> This template definition is invalid with g++ 3.3.2
>
> template < class T >
> class A { /*...*/ };
>
> template < class T >
> class B : public A < B > { /*...*/ }
>
> g++ rejects this with an error:
>
> policy.cpp:8: error: type/value mismatch at argument 1 in template parameter
> list for `template<class T> class A'
> policy.cpp:8: error: expected a type, got `B'
> policy.cpp:8: error: invalid base-class specification
Indeed. B is not a type -- B is a class template, not a
class. Instantiations of B are types (classes). The
class template A was declared as having a single template
parameter, specifically a class.
> In contrast, the following works:
>
> template < class T >
> class B : public A < B <T> >
> ^^^^^
Because in this situation you have supplied a class as
A's template parameter.
> Obviously g++ does not recognize the reference to B as a type, unless it is
> explicitely specialized with the template parameter as B<T>
g++ is quite right; B is not the name of a type.
> The standard states:
>
> 14.6.1 Locally declared names
> 1 Within the scope of a class template, when the name of the template is
> neither qualified nor followed by <,
> it is equivalent to the name of the template followed by the template
> parameters enclosed in <>.
>
> Thus, i'm asking: WHERE does the 'scope of a class template' start ? Is it
> just after the name has been mentioned - in this case g++ has a bug, or is
> it after the opening brace - in this case g++ behaves correctly.
>
> BTW, VC7 accepts both definitions.
It does? Upgrade to 7.1, maybe. What does 7.0 do with
the case where you specified a template template parameter
to A instead of a type?
-- James
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: technews@kangaroologic.com ("Jonathan Turkanis")
Date: Mon, 19 Jan 2004 01:10:14 +0000 (UTC) Raw View
"Martin Cornelius" <Martin.Cornelius@t-online.de> wrote in message
news:bucfrn$klq$03$1@news.t-online.com...
> Having started to work through A. Alexandrescu's great 'Modern C++
Design'
> book, i encountered the following problem:
>
> This template definition is invalid with g++ 3.3.2
>
> template < class T >
> class A { /*...*/ };
>
> template < class T >
> class B : public A < B > { /*...*/ }
>
> g++ rejects this with an error:
>
> policy.cpp:8: error: type/value mismatch at argument 1 in template
parameter
> list for `template<class T> class A'
> policy.cpp:8: error: expected a type, got `B'
> policy.cpp:8: error: invalid base-class specification
>
[I posted another reply which missed the point. My apologies]
I think your question can be answer by looking at the beginning of
clause 9
A class-name is inserted into the scope in which it is declared
immediately
after the class-name is seen. The class-name is also inserted into
the scope
of the class itself; this is known as the injected-class-name.
The distinction between drawn between (i) that portion of the
enclosing scope which immediately follows the class name and (ii) the
scope of the class makes it pretty clear that the scope begins with
the opening "{". (I thought this would be stated more explicitly
somewhere, maybe in 3.3.6, but I don't see it.)
If this is correct, then VC is wrong. All the non-microsoft compilers
I tried gave an error similar to the one you mentioned above.
The passage you cited from 14.6.1 raises an issue I had never
considered: The following should not compile:
template<template<typename> class T>
struct A { };
template<typename T>
struct B {
A<B> a;
};
Here A<B> should be treated as short for A< B<T> >, which is an error,
since A expects a template. I tried this on VC7.1, Codewarrior 8.0,
Borland 5.6.4, Intel 7.1 GCC 3.3.1 and Comeau 4.3.3.
Comeau, VC and Intel spotted the error; the others treated it as if it
were written A< ::B >.
Jonathan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]