views:

297

answers:

3

I would like to declare a template as follows:

template <typename T>
{ 
  if objects of class T have method foo(), then 
   const int k=1
  else 
   if class has a static const int L then
    const int k=L
   else 
    const int k=0;


}

How can I do this? In general, I would like a mechanism for setting static consts based on properties of T (or typedef defined inside T).

A: 

Hard to say answer in current form, because problem domain isn't clear.

Still, you could try using the type traits technique, which enhances your templated class by adding parameters specific to only objects which have type T.

I'm pretty sure, that using type traits could solve your problems, still, using them and writing / making old routines generic could sometimes get tricky.

Kotti
A: 

Using boost's enable_if some of such functionality can be implemented using traits. But since C++ lacks reflection questions like "does this class contains this method/member?" are not easy to resolve

Ismael
Too bad I wasn't around at the time to give the poster a useful answer. I posted it now.
Noah Roberts
+4  A: 

The outer part is of course quite easy. Use boost::mpl::if_ to decide which int_ type to return from your metafunction and then access the value in it. No big deal.

The part where you try to find out if type X has a function f() is still fairly straight forward but unfortunately you'll not find a generic answer. Every time you need this kind of inspection you'll have to write a custom metafunction to find it out. Use SFINAE:

  template < typename T >
  struct has_foo
  {
    typedef char (&no)  [1];
    typedef char (&yes) [2];

    template < void (T::*)() >
    struct dummy {};

    template < typename S >
    static yes check( dummy<&S::foo> *);

    template < typename S >
    static no check( ... );

    enum { value = sizeof(check<T>(0)) == sizeof(yes)  };
  };

Edit: Oh, and create a checker for your static const L with BOOST_MPL_HAS_XXX()

Noah Roberts
Nice, I'll keep this snipet around.
Ismael