Is it possible (and is it a good idea) to conditionally define methods for some container class (template<typename ThingType> class Container
) depending on the type of its elements? I first thought it was possible after reading about std::enable_if
, but now I am not certain I understand.
Below is my attempt (click here to run on ideone). In the case that std::is_base_of<ThingBase, ThingType>::value
is false
, a return type for p
will not be defined. I figured the compiler would just instantiate the object of a class without that method. But it turns out it doesn't compile.
Is there another tool for the job? Or should I write two Container
-like classes that have different behavior depending on what ThingType
is? Or maybe this is a job for a specialization.
#include <iostream>
#include <type_traits>
#include <vector>
class ThingBase {
public:
virtual void printHi() = 0;
};
class Thing : public ThingBase
{
void printHi(){
std::cout << "hi\n";
}
};
template<typename ThingType>
class Container{
private:
std::vector<ThingType> m_things;
public:
typename std::enable_if<std::is_base_of<ThingBase, ThingType>::value>::type p()
{
m_things[0].printHi();
};
};
int main() {
//Container<Thing> stuff; // works!
Container<int> stuff; // doesn't work :(
return 0;
}
Edits:
The error message from the compiler is
prog.cpp: In instantiation of ‘class Container<int>’:
prog.cpp:36:17: required from here
prog.cpp:26:78: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
typename std::enable_if<std::is_base_of<ThingBase, ThingType>::value>::type p()
@StoryTeller - Unslander Monica I don't intend for this method to be overloaded. I want it to be available to the end user whenever it makes sense for it to be available. There will only be one of these p
methods, and it should take only one (relatively simple) signature.