I need to store multiple types of a template class in a single vector.
Eg, for:
template
class templateClass{
bool someFunction()
This solution inspired by Sean Parent's C++ Seasoning talk. I highly recommend to check it out on youtube. My solution simplified a bit and the key is to store object in method itself.
Create a class that will invoke method of stored object.
struct object {
template
object(T t)
: someFunction([t = std::move(t)]() { return t.someFunction(); })
{ }
std::function someFunction;
};
Then use it like this
std::vector
For several methods use shared pointer to share object between methods
struct object {
template
object(T&& t) {
auto ptr = std::make_shared>(std::forward(t));
someFunction = [ptr]() { return ptr->someFunction(); };
someOtherFunction = [ptr](int x) { ptr->someOtherFunction(x); };
}
std::function someFunction;
std::function someOtherFunction;
};
Primitive types (such as int, float, const char*) or classes (std::string etc.) may be wrapped in the same way as object class do but behave differently. For example:
struct otherType {
template
otherType(T t)
: someFunction([t = std::move(t)]() {
// Return something different
return true;
})
{ }
std::function someFunction;
};
So now it is possible to add types that does not have someFunction method.
v.emplace_back(otherType(17)); // Adding an int
v.emplace_back(otherType("test")); // A string
After some thoughts what we basically done in first solution is created array of callable functions. So why not just do the following instead.
// Example class with method we want to put in array
struct myclass {
void draw() const {
std::cout << "myclass" << std::endl;
}
};
// All other type's behaviour
template
void draw(const T& x) {
std::cout << typeid(T).name() << ": " << x << std::endl;
}
int main()
{
myclass x;
int y = 17;
std::vector> v;
v.emplace_back(std::bind(&myclass::draw, &x));
v.emplace_back(std::bind(draw, y));
for (auto& fn : v)
fn();
}
Solution nr. 1 is definitely an interesting method that does not require inheritance nor virtual functions. And can be used to other stuff where you need to store a template argument to be used later.
Solution nr. 2, on the other hand, is simpler, more flexible and probably a better choice here.