Boost logo

Boost :

Subject: Re: [boost] a (useful?) crtp trick
From: pavel (paul.cpprules_at_[hidden])
Date: 2012-08-26 08:28:21


 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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk