Constraining a template class argument to a derived class of base

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • amkg

    Constraining a template class argument to a derived class of base

    Hello world,

    I'm trying to figure out some way to constrain a template class
    argument for a member function definition, such that the template
    class argument must, totally, absolutely be a derived class of a
    certain base class.

    My current solution is:

    class Base {
    // etc..
    };

    class BaseHolder {
    //etc
    public:
    template<class T>
    T* make(void) {
    /*This one!*/
    Base* _check_derived_ from_Base_ =
    static_cast<Bas e*>((T*) 0);
    return new(alloc(sizeo f(T))) T();
    }
    };

    It *seems* to work, but I think it's kind of hackish. Is there a
    better, standards-defined way where I can specify that the class T in
    the template should derive from "Base"?

    Sincerely,
    AmkG
  • Victor Bazarov

    #2
    Re: Constraining a template class argument to a derived class ofbase

    amkg wrote:
    Hello world,
    >
    I'm trying to figure out some way to constrain a template class
    argument for a member function definition, such that the template
    class argument must, totally, absolutely be a derived class of a
    certain base class.
    >
    My current solution is:
    >
    class Base {
    // etc..
    };
    >
    class BaseHolder {
    //etc
    public:
    template<class T>
    T* make(void) {
    /*This one!*/
    Base* _check_derived_ from_Base_ =
    static_cast<Bas e*>((T*) 0);
    return new(alloc(sizeo f(T))) T();
    }
    };
    >
    It *seems* to work, but I think it's kind of hackish. Is there a
    better, standards-defined way where I can specify that the class T in
    the template should derive from "Base"?
    Look in the archives for 'boost::enable_ if', there will probably be an
    example of determining whether the class is a base class or a derived
    class of 'T'... Not sure if it's going to become standard (it isn't)
    but Boost libraries are widely used nowadays (and most are free, IIRC).

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask

    Comment

    • amkg

      #3
      Re: Constraining a template class argument to a derived class of base

      On Nov 6, 12:09 am, Michael DOUBEZ <michael.dou... @free.frwrote:
      amkg a écrit :
      >
      >
      >
      Hello world,
      >
      I'm trying to figure out some way to constrain a template class
      argument for a member function definition, such that the template
      class argument must, totally, absolutely be a derived class of a
      certain base class.
      >
      My current solution is:
      >
      class Base {
      // etc..
      };
      >
      class BaseHolder {
      //etc
      public:
          template<class T>
          T* make(void) {
              /*This one!*/
              Base* _check_derived_ from_Base_ =
                  static_cast<Bas e*>((T*) 0);
              return new(alloc(sizeo f(T))) T();
          }
      };
      >
      It *seems* to work, but I think it's kind of hackish.  Is there a
      better, standards-defined way where I can specify that the class T in
      the template should derive from "Base"?
      >
      Use boost static_assert and is_derived:
      BOOST_STATIC_AS SERT(is_derived (T,Base));
      >
      If you don't want boost, the usual way to make the template
      instantiation fail if a conversion cannot occur:
      >
      template <class T, class B>
      struct assert_derived
      {
           //declare static constant to avoid T default construtible
           static const T x;
      >
           //convert type to its pointer
           template <class X>
               static X* to_pointer(X const&);
      >
           //if can convert
           static char convert_to_base (B const*);
      >
           //this fail if cannot convert to pointer
           static const bool test=sizeof(con vert_to_base(to _pointer(x)));
      >
      };
      >
      Then in your code:
      assert_derived< T,Base>();
      >
      But the error code generated if far from meaningful.
      >
      --
      Michael
      Thanks, I'll check out that template. Currently the hack I posted
      gives a reasonable error in gcc - invalid static_cast from type ‘Bar*’
      to type ‘Base*'. If the error code of that template is worse, I'll
      stick with my hack I guess.

      Comment

      Working...