alan
11/5/2008 10:23:00 PM
On Nov 6, 12:09 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:
> 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<Base*>((T*) 0);
> > return new(alloc(sizeof(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_ASSERT(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(convert_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.