Boost logo

Boost :

Subject: [boost] metaprogramming: associating a type with another type
From: DE (satan66613_at_[hidden])
Date: 2010-01-29 12:47:57


hi boosters
while solving my own design problems i accidentally discovered an
interesting technique

let's assume we want to associate some value (a type) to a newly
created type so we can easily access the associated type during
metaprogramming
let's call the associated type a property
then we have the following property types:

  struct property0 {};
  struct property1 {};
  struct property2 {};

now we want to access the associated property for an arbitrary type in
a natural traits manner:

  property<arbitrary_type>::type

it appears we can implement it almost trivially (if know how)
(let's assume we have portable typeof() facility)
consider the code

  //the return type of this function appears to be the default property
  template<typename type> property0 get_prop(type*); //do not implement!

  template<typename t>
  struct property {
    typedef typeof(get_prop((type*)42) type;
  };

  template<typename type, typename p = typename property<type>::type>
  struct base {
    friend p get_prop(type*) { return p(); }
  };

  template<typename type>
  void foo(const base<type>&) //handles ALL types derived from base
  {
    typedef typename property<type>::type associated_property;
  }

  template<typename type>
  void bar(const base<type, property2>&) //handles ONLY types with property2
  {}

  struct s : public expression<s> //default property used here
  {};

  struct s1 : public expression<s1, property1>
  {};

  struct s2 : public expression<s2, property2>
  {};
  
  int main()
  {
    foo(s());
    foo(s1());
    foo(s2());
    //bar(s()); //should not compile
    //bar(s1()); //should not compile
    bar(s2());
    return 0;
  }
  
even with the lack of typeof(), given a fixed set of properties it
is very easy to implement this technique
see working example at http://codepad.org/qXkESprl

personally i see it as extremely useful for generic lib writers for
some designes (of course if appropriately applied) as well as for
users of such libs

i would appreciate any thoughts on improvement of this technique
within C++98 standard
also any thoughts on portability are welcome

if you have questions about how and/or why does it work feel free to ask

--
Pavel

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