Boost logo

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