0

I have a class ClassType that is a parent for some other classes. I want to create a template that can only have the ClassType (and its children) type, like:

template< ClassType > class ClassABC
{
   std::shared_ptr< ClassType > m_member;
   // ...
public:
   ClassABC< ClassType >(std::shared_ptr< ClassType >& objIn) : m_member(objIn) {}
   void foo( int v1, int v2); // the function does an operation general to ClassType
}

But it is not correct. Is there a way to do it?


I want to have some kind of specializations like:

template<> class ClassABC< B >
{
   std::shared_ptr< B > m_member;
   // ...
public:
   ClassABC< B >(std::shared_ptr< B >& objIn) : m_member(objIn) {}
   void foo( int v1, int v2); // the function does some operation specific to B
}

and for the other classes (A and C) it does the generic operation.

sop
  • 3,445
  • 8
  • 41
  • 84
  • possible duplicate of [Template Constraints C++](http://stackoverflow.com/questions/122316/template-constraints-c) – Jean-Baptiste Yunès Dec 12 '14 at 15:07
  • @Jean-BaptisteYunès: that thread does not have relevant answers. :( mostly due to it being very dated. ideally we'd just close this question, add proper answer over there, and all would be well. but nobody's going to remove the misleading answers there. – Cheers and hth. - Alf Dec 12 '14 at 15:19
  • 1
    As it turns out I was wrong about no relevant answers; see [this comment](http://stackoverflow.com/questions/27446404/is-there-a-way-of-defining-a-template-on-an-existing-type/27446440?noredirect=1#comment43342965_27446440) and lead-up. – Cheers and hth. - Alf Dec 12 '14 at 21:20

1 Answers1

3

You can use std::enable_if in conjunction with std::is_base_of.

For example,

#include <type_traits>      // std::is_base, std::enable_if

using std::enable_if;
using std::is_base_of;

class Base {};

template<
    class Type,
    class Enabled = typename enable_if< is_base_of<Base, Type>::value, void >::type
    >
class ClassABC
{
public:
    void foo() {}
};

class A: public Base {};
class B: public Base {};
class X {};

using At = ClassABC<A>;
using Bt = ClassABC<B>;
using Ct = ClassABC<Base>; 

using Xt = ClassABC<X>;  //! Nope.

auto main() -> int
{}
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • So you think that your usage of `is_base_of` is very different than the ones int the answers of the *old* question I mentioned ? – Jean-Baptiste Yunès Dec 12 '14 at 15:55
  • And if I have a member of type T, like `std::shared_ptr< T > m_member`? I'll update, sorry. – sop Dec 12 '14 at 15:56
  • I am getting some errors over there in the constructor – sop Dec 12 '14 at 15:59
  • Sorry, I just need to add the `Enable`... I'll comment if anything else is going wrong – sop Dec 12 '14 at 16:01
  • 1
    @Jean-BaptisteYunès: I don't see any `enable_if` in the thread you referenced. And neither does Firefox (the browser, it has a text search function). I don't see any DIY solution like `enable_if` either. – Cheers and hth. - Alf Dec 12 '14 at 16:02
  • why add an inferior syntax in addition to the one used here? it covers it all. anyway, http://www.goodreads.com/quotes/639349-multiple-exclamation-marks-he-went-on-shaking-his-head-are – Cheers and hth. - Alf Dec 12 '14 at 16:08
  • There is an answer in the mentioned thread that is exactly the solution you gave BUT uses `static_assert` to give a more convenient compiler message. That answer is at least as modern as yours, it has been written in Apr'14. The question is exactly the same, good answer are present and a good solution is given. – Jean-Baptiste Yunès Dec 12 '14 at 20:34
  • 1
    @Jean-BaptisteYunès: Sorry, I didn't see that. It's an acceptable answer for most in-practice cases, although with `static_assert` it places the checking in the template implementation rather than up front in the declaration. But on the third hand, with `export` removed from the language that's not so critical anymore; I think it would only really matter for a template with explicit complete specializations compiled separately (yes you can do that). So I think the answer you point to means that I was wrong about "not ... relevant answers". Hm. – Cheers and hth. - Alf Dec 12 '14 at 21:18
  • Ok I see that you understand my point of view on the question. Best regards! – Jean-Baptiste Yunès Dec 12 '14 at 22:25