I just ran into an issue where code that I was sure that is compilable
and works turned out to not compile on GCC 4.2.1. Before dismissing it
as a GCC bug I decided to have it tested on other systems and while
MSVC 2005 and C++ Builder 6 work fine, Comeau on-line behaves just as
GCC (GCC 4.1.0 and 3.4.4 and probably all the others give the same
errors as 4.2.1).
Since both GCC and Comeau give errors at the same point, chances are
that my code is wrong. If that's the case, I wonder how to make it
right. Also, I wonder if it is right that uncommenting the line with
the global "void f(int, float)" makes the errors go away.
So here's the code:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
template <typename T>
struct X
{
template <typename U> int f();
};
//template <typename T> void f(int, float); // any parameter(s) would do
template <typename T>
int g()
{
X<T> tmp;
return tmp.f<int>(); // error
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
There's no need for an instantiation of g().
What I find rather puzzling is that uncommenting the line with the
global template function "f" makes everything compile with GCC and
Comeau. While this takes care of my problem, I suspect that it's not
supposed to. So: what happens here and what should be happening?
Thanks,
Ciobi
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
> Since both GCC and Comeau give errors at the same point, chances are
> that my code is wrong. If that's the case, I wonder how to make it
> right. Also, I wonder if it is right that uncommenting the line with
> the global "void f(int, float)" makes the errors go away.
>
> So here's the code:
>
> template <typename T>
> struct X
> {
> template <typename U> int f();
>
> };
>
> //template <typename T> void f(int, float); // any parameter(s) would do
>
> template <typename T>
> int g()
> {
> X<T> tmp;
> return tmp.f<int>(); // error
>
> }
The compiler needs some help in identifying a template specialization
inside another template specialization, such as f<int>() in this case:
template <typename T>
int g()
{
X<T> tmp;
return tmp.template f<int>(); // OK
}
Greg
You are missing the keyword "template" here:
return tmp.template f<int>();
tmp is of a dependent type X<T> with T a template parameter of this
template. This means that you need to use the template keyword to
have f considered to be a member template.
>
> There's no need for an instantiation of g().
>
> What I find rather puzzling is that uncommenting the line with the
> global template function "f" makes everything compile with GCC and
> Comeau. While this takes care of my problem, I suspect that it's not
> supposed to. So: what happens here and what should be happening?
It is puzzling(!) but it's definitely not the right fix. :-)
--
Charles Bailey
http://ccgi.hashpling.plus.com/blog/
What f is or isn't depends on the template parameter T.
You must inform the compiler about what you assume f to be.
return tmp.template f<int>();
Cheers, & hth.,
- Alf
--
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?