20

Is there any possibility to force a template to be from a certain base class so that I can call the base class function?

template <class T> void SomeManager::Add(T) { T->CallTsBaseClassFunction(); //... do other stuff } 
3
  • Possible duplicate of Template Constraints C++. Commented Feb 13, 2011 at 14:07
  • 1
    Why don't you just call the function and see if it works? Commented Feb 13, 2011 at 14:21
  • 3
    @Bo Persson: because that only guarantees nominal, not structural inheritance. You might end up calling Random::CallTsBaseClassFunction if class Random just happens to implement a function by the same name. Commented Feb 14, 2011 at 10:34

3 Answers 3

25

Sure, you can combine type traits with SFINAE:

#include <type_traits> template <class T> typename std::enable_if<std::is_base_of<your_base_class, T>::value, void>::type SomeManager::Add(T) { T->CallTsBaseClassFunction(); //... do other stuff } 

Although I don't really see the benefit here.

Sign up to request clarification or add additional context in comments.

7 Comments

The benefit is that you can force the users of your class to inherit some base class, which contains some abstract function.
@Yves But if it's a template then what's the advantage of virtualization? You already get static dispatch.
@user975989 No, what I meant is, for example, you develop a template class, which is to process data with different type: void handle(T t) { this.processData(t.getValue());}. Other people can develop different data, such as class DataTypeA, class DataTypeB. Now, you must force the writer of DataTypeA and DataTypeB to write the member function getValue(). To do so, you can write an abstract class, containing an abstract function getValue(). If DataTypeA didn't inherit the abstract class, generate an ERROR.
@Yves Sure, but if you just call the function template and DataTypeA doesn't have getValue(), it would still error.
@Yves that's what I mean. You don't need an abstract base class.
|
12

Worth to mention that it can be done at compile time in a more readable fashion with static_assert. Something in the lines of:

class Base {}; template<class B> class Template{ static_assert(std::is_base_of<Base, B>::value, "B must derive from nmspc::Base"); } 

It works even when B is exactly Base. If Base is itself a templated class it becomes more complicated but it can still be done and there's plenty of resources online.

Comments

9

The easiest solution is to add a snippet of code that compiles only if it's what you expected:

template <class T> void SomeManager::Add(T t) { assert((Base const*)&t); // T must inherit from Base to allow T*->Base* conversion. t.CallTsBaseClassFunction(); //... do other stuff } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.