template inheritance check

This topic is 5053 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

class D {};

template < typename T >
class C
{
};


what code could I add to C to enforce that T must derive from D?

Share on other sites
Quote:
 Original post by 0xCHAOS *** Source Snippet Removed ***what code could I add to C to enforce that T must derive from D?

If you have boost:

#include <boost/utility/enable_if.hpp>#include <boost/type_traits/is_base_and_derived.hpp>class D {};template < typename T         , typename Enabler = void         >class C;template < typename T >class C< T       , typename ::boost::enable_if< ::boost::is_base_and_derived< D                                                                  , T                                                                  >                                    >::type       >{  /* your class definition goes here */};

This will work for both public and non-public bases. It makes it so the definition is literally only defined if T derives from D. If you want to have it only work with public bases, use ::boost::is_convertible with a pointer to T and a pointer to D instead of ::boost::is_base_and_derived.

If your compiler isn't compliant with SFINAE, you can also use a BOOST_STATIC_ASSERT inside the class definition instead of selective partial specialization.

Share on other sites
Polymorphic_OOP - I'd probably use boost's static assertions instead of mucking with MPL:

#include <boost/static_assert.hpp>#include <boost/type_traits.hpp>class D {};template<class T>class C{  // need two (()) because of the comma  BOOST_STATIC_ASSERT((::boost::is_base_and_derived<D,T>::value));  // your code here.};

And I believe you meant Partial Template Specialization, not Substitution Failure Is Not An Error.

Share on other sites
Quote:
 Original post by FrunyPolymorphic_OOP - I'd probably use boost's static assertions instead of mucking with MPL

Actually, the code I provided doesn't even use mpl Fruny (though it uses the abstract concept of a bool metavalue). Even still, there is absolutely nothing wrong with it if I did use mpl in the example -- it's a beautiful library. The reason I only suggested static assertions as an alternative to enable_if is because, in my opinion, enable_if more clearly defines the situation. A selective specialization means, quite literally, that the type isn't defined when you pass those template parameters, whereas a static assertion means that the type is defined with error. Selective specialization also often gives a more concise error message.

Quote:
 And I believe you meant Partial Template Specialization, not Substitution Failure Is Not An Error.

No, I meant SFINAE. That's how enable_if works. It will only partially specialize if the condition is met, since if the condition is false, substitution will fail.

Share on other sites
arg... I keep trying to post a message explaining a problem I'm still having, but it seems the forums get messed up for a few moments every time I do, so heres a link to the post I'm trying to make:

Share on other sites
Ah, so somebody did see that totally failed post before I deleted it [lol]. I was a bit tired and not thinking clearly and that version was totally flawed - it doesn't cover derived types at all. Instead I'll offer this:
class D {};class F : public D{int i;};class E {};class True{	char m;};class False{	unsigned long m;};class NoType{};struct Type{	typedef bool result;};template <typename T>True IsSame(T*, T*);template <typename T, typename F>False IsSame(T*, F*);template <typename D, typename T>struct DerivedFromImpl{	static D d;	static T t;	static const bool result = sizeof(IsSame<D>(&d, &t)) == sizeof(True) || sizeof(IsSame<T>(&d, &t)) == sizeof(True);};template <bool Switch, typename R1, typename R2>struct Select{};template <typename R1, typename R2>struct Select<true, R1, R2>{	typedef R1 result;};template <typename R1, typename R2>struct Select<false, R1, R2>{	typedef R2 result;};template <typename D, typename T>struct DerivedFrom{	typedef typename Select<DerivedFromImpl<D, T>::result, Type, NoType>::result result2;	typedef typename result2::result result;};template < typename T >class C{	private:		typedef typename DerivedFrom<T, D>::result mustDeriveFromD;};int main(){	C<D> ok;	C<F> ok2;//	C<E> fail;}

I make no guarantee of its correctness or portability, but it seems to work on GCC, BCB and VC++. Most of the ideas are copied from the boost source, but I had to find workarounds for things that I still don't know why they didn't work - or even why boost does it that way in the first place!

Enigma

Share on other sites
I can't use that method because it creates static instances of both D and T, and these are singleton types. However, I just stumbled upon an amazingly simple solution: adding the line

SingletonBase * pb = s_inst;

in both the GetInst ( ) and AddDependency ( ) methods.

Anyhow, thanks for the help!

1. 1
2. 2
3. 3
4. 4
Rutin
21
5. 5

• 9
• 13
• 19
• 14
• 9
• Forum Statistics

• Total Topics
632936
• Total Posts
3009315
• Who's Online (See full list)

There are no registered users currently online

×