
Mathias wrote on Saturday, August 25, 2012 at 19:31:53:
What's the advantage over
template<class T> struct tag_of;
template<class Derived> struct Base { typedef typename tag_of<Derived>::type tag; };
struct Foo : Base<Foo> { };
template<> struct tag_of<Foo> { typedef void type; };
thanks for the question the advantage is that you may completely ignore the tag as in template<typename type> void f(const Base<type>&); or you may use it straightforwardly like template<typename type typename tag> void g(const Base<type, tag>&); and the most important -- you may explicitly specify tag for a function like template<typename type> void h1(const Base<type, tag1>&); then a type tagged other than 'tag1' can not be supplied to 'h()', for example struct Foo : Base<Foo, tag1> {} struct Bar : Base<Bar, tag2> {} int main() { Foo foo; f(foo); g(foo); h1(foo); Bar bar; f(bar); g(bar); h1(bar); //does not compile by design: tag mismatch } declaration is crystal clean (read: self documenting), no need to use enable_if, etc. as a bonus compilers -- at least msvc and gcc -- produce nice error messages like "there is no such function 'f' taking 'type'" though gcc is much nicer in this regard giving complete, exhaustive description of the error -- Pavel P.S. if you notice a grammar mistake or weird phrasing in my message please point it out