Re: gcc 4.1.2 bug?
Alberto Ganesh Barbati wrote:
Greg Herlihy ha scritto:
The problem with this expectation, as I see it, is this: how can the
compiler tell what Attr's type parameter is when instantiating just the
Table record class template above? There is no way of recovering RD's
enclosing class template (or even to tell whether it has one) from the
template template parameter used to instantiate RD - and being able to
recover Attr's type parameter is necessary in order to match the
i_record_descriptor specialization. So without any way of testing
whether the specialization is a match, the compiler instantiates RD
with its general class template and not the provided specialization.
Nonsense. Consider the Attr ctor that references TableRecord:
Attr()
{
TableRecord<A, 1, i_record_descriptor> tr;
}
In this scope, A indicates the template parameter used to instantiate
the template Attr and i_record_descriptor clearly binds to
Attr<A>::i_record_descriptor. So what TableRecord gets is
Attr<A>::i_record_descriptor which provides all information needed to
match the partial specialization.
Just because we know A's type does not mean that the compiler no longer
has to deduce it for itself. And the fact that we can tell whenever A
in Attr<A> is the same type as i_record_descriptor's first type
argument, T - is precisely what leads some to think (incorrectly) that
the compiler has the same information and will see that the types match
- and therefore choose to instantiate i_record_descriptor's's partial
specialization just as we would have decided.
In reality, even when A and T are the same type - a C++ compiler
instantiates i_record_descriptor's general template. Because in order
to have choosen the specialization, the compiler would have had to
deduce A's type so that it could be compared with T (whose type it does
know). But how does the compiler find out A's type? Let's try to find
out A's type ourselves. But first we'll hide the name of A's type with
a typedef, X, so that we are forced to deduce the actual type.
So we need to decide whether:
Attr<X>::i_record_descriptor<char, 3> record;
should be instantiated with the i_record_descriptor specialization or
its general template. In other words how do we recover the X out of
this type to check whether X is type char?
The answer is that we cannot. We are not able to determine what type X
is - because X is a "non-deduced" type in this context. So even when X
is char - and we can see that the types A and T are the same - the
compiler will still be unable to deduce the match. So the
i_record_descriptor specialization will in fact never be choosen for
any of i_record_descriptor's instantiations.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]