Constraining a template class argument to a derived class of base

A

amkg

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"?

Sincerely,
AmkG
 
M

Michael DOUBEZ

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.
 
A

amkg

amkg a écrit :









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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top