Re: Is it a g++-4.1 bug ?
Manuel.Yg...@inrialpes.fr schrieb:
template<typename T>
struct test
{
T o;
template<typename I>
struct inner
{
I* ptr;
const inner<I>& operator*() const;
[..]
};
typedef inner< test<T> > const_iterator;
};
template<typename T>
template<typename I>
const test<T>::inner<I>& test<T>::inner<I>::operator*() const
{
return *this;
}
[..]
For me it does not compile, the compiler complains:
invalid declarator before '&' token in the operator*() definition.
The compiler is right, the shown out-of-class definition of
operator* should not compile, v.i.
But if you uncomment the 3 lines and you comment the operator definition
outside the class, the code compiles.
Yes, because by doing this you bypass the need
to provide a fully qualified name of the member template,
so the problem does not occur.
By providing the complete qualification you stumble
accross two problems for this specification:
template<typename T>
template<typename I>
const test<T>::inner<I>& ...
1) For proper interpretation what "test<T>::inner"
means you are required to tell the compiler that
inner is a type (and not another non-type name).
Therefore you need a leading typename:
template<typename T>
template<typename I>
const typename test<T>::inner<I>& ...
This need is explained in 14.6/2 ff.
2) Now the compiler understands that test<T>::inner
is a type and the next parsing problem is the following
< character, which *could* be interpreted as less
operator. To help then compiler you need to say that
the following is a template-id:
template<typename T>
template<typename I>
const typename test<T>::template inner<I>& ...
Ca va!
This second problem is explained in 14.2/4:
"When the name of a member template specialization appears
after . or -> in a postfix-expression, or after nested-name-specifier
in a qualified-id, and the postfix-expression or qualified-id
explicitly
depends on a template-parameter (14.6.2), the member template
name must be prefixed by the keyword template. Otherwise the
name is assumed to name a non-template".
Afaik both "helper" keywords are required in this situation.
Interestingly even modern compilers seem to accept the
incomplete versions, e.g.
- Comeau 4.3.8 Alpha as well as 4.3.3 Beta accept your
*original* version. This is IMO an error and should be reported.
- VS 2005-SP1 correctly chokes about the missing typename
but accepts the missing template.
- My quite old mingw compiler (gcc version 3.4) does only
accept the complete name as shown above.
More confusing: with the first version of the code if you remove the first
const keywork, the compiler nciely informs you:
What do you mean here? Did you remove the const specifier
from both the declaration *and* the definition or only from one
of them?
prototype for 'test<T>::inner<I>& test<T>::inner<I>::operator*() const'
does not match any in class 'test<T>::inner<I>'
error: candidate is: const test<T>::inner<I>&
test<T>::inner<I>::operator*() const
Thus in the operator definition the error is not in the return parameter
declaration.
Perhaps it is in the templates parameters:
template<typename T>
template<typename I>
But if you remove all the const keywords in the first code version, the
code compiles.
This is definitively a compiler bug, because the issue is not
related to cv qualifications.
I think either I need a voodoo consultation with a c++ guru or I have to
emmit a bug report to gcc.
gcc is right in not accepting your original code but should accept
the above proposed naming. I assume there is a gcc compiler error,
if it *accepts* the code after removing all const specifiers!
Greetings from Bremen,
Daniel Kr|gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]