Connecting Tech Pros Worldwide Forums | Help | Site Map

Constraining a template class argument to a derived class of base

amkg
Guest
 
Posts: n/a
#1: Nov 5 '08
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

Victor Bazarov
Guest
 
Posts: n/a
#2: Nov 5 '08

re: Constraining a template class argument to a derived class of base


amkg wrote:
Quote:
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"?
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
amkg
Guest
 
Posts: n/a
#3: Nov 5 '08

re: Constraining a template class argument to a derived class of base


On Nov 6, 12:09*am, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
amkg a écrit :
>
>
>
Quote:
Hello world,
>
Quote:
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.
>
Quote:
My current solution is:
>
Quote:
class Base {
// etc..
};
>
Quote:
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();
* * }
};
>
Quote:
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.
Closed Thread