
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