|
Boost : |
From: Simon Buchan (simon_at_[hidden])
Date: 2005-10-11 17:35:45
Robert Ramey wrote:
<snip>
> Hmmm - here is a situation that I come across:
>
> class my_archive {
> ....
> };
>
> template<class Arg>
> class my_templated_archive{
> };
>
> template<class Archive, T>
^ you forgot 'class' here :-)
> void serialize(Archive & ar, T &t, const unsigned int version){
> ...
> ar.template register_type<T>(); // ok - I think
> ...
> }
>
> void serialize(my_archive & ar, T &t, const unsigned int version){
> ...
> ar.template register_type<T>(); // syntax error? or not?
> ...
> }
>
> Truth is I can't never keep these kinds of rules straight.
>
> Robert Ramey
In the first: ar is dependant, so the lookup of register_type cannot
happen until serialize is instatiated: but the syntax must be checked
due to two-stage lookup. (which, believe it or not, actually helps more
than it hinders, as long as you arn't a compiler vendor) Since it has
no idea what register_type is (it could be an int, for all it knows) it
simply assumes it isn't a template and treats it as a couple of
comparisons. (Which gives an error when it finds out later that
register_type is a template) Which is why you need the template keyword
there.
In the second, it can look up all the types right there and then, so
there is no need for (and is illegal to add) the disambiguation.
BTW: it doesn't matter whether *ar* comes from a template or not,
they're all classes at that point. What matters is that it's being
*used* in a template and is dependant on a parameter, and thus can't be
looked up right there and then, meaning the compiler doesn't know what
register_type is. Nifty huh? </sarcasm>
The good news is that most of the time, none of this matters much to
you. If it complains, add the keyword and be thankful your compiler is
conformant.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk