|
Boost : |
Subject: Re: [boost] a (useful?) crtp trick
From: pavel (paul.cpprules_at_[hidden])
Date: 2012-08-27 06:49:52
Sebastian wrote on Monday, August 27, 2012 at 12:28:16:
> On 24.08.2012 19:50, pavel wrote:
> I think this only happens to work by accident, because compilers tend to
> defer instantiation of function templates until the end of the
> translation unit, when a proper instantiation of Base is available. But
> without a compiler that doesn't I don't think I can come up with code
> that shows this.
the thing is in the order of instantiation
when you define a concrete type, e.g.
struct Foo : Base<Foo, tag1> {};
the 'Base' template is instantiated and the friend function
declaration, namely
tag1 get_tag(Foo*);
comes into play at this point
further when you supply an object of 'Foo' to a template function
taking a ref to 'Base' the second template argument (here -- tag) is
deduced according to the declaration of 'Base':
template<typename the_type,
typename tag = typename base_tag<type>::type>
struct Base { friend tag get_tag(the_type*); }
the compiler evaluates the default type instantiating 'base_tag'
(remember that the appropriate 'Base' is already instantiated and
needed 'get_tag()' is in the game either)
so the 'base_tag' does nothing more than just wrapping the decltype
expression in a typedef:
typedef decltype(get_tag((the_type*)314159)) type;
at this point the compiler have the complete set of pieces of the
puzzle:
- 'get_tag()' declaration from the 'Base' template instatioation earlier
- 'the_type' deduced from the function argument as in
template<typename the_type> void f(const Base<the_type>&);
so the compiler gets the exact type associated with 'the_type' ('Foo'
in this example), namely -- 'tag1' according to 'Foo' definition:
struct Foo : Base<Foo, tag1> {};
and we have now the deduced type for the argument of a function,
namely 'Base<Foo, tag1>', which is exactly the base class of the 'Foo'
so any (modern) standard conforming compiler should do this (feel free
to prove me wrong)
sorry for lengthy explanation
> In any case, this makes *my* head hurt, and that's saying something.
just use it if you'd like to
-- Pavel P.S. if you notice a grammar mistake or weird phrasing in my message please point it out
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk