|
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