I'm currently coding a program in c using a template class:
template<typename TYPE>
class TemplateClass {
private:
TYPE t;
};
I have another class which acts as manager of my TemplateClass
which should store multiple instances of this class in a vector. Different instances should have different types e.g. int
, std::string
, etc.. Speaking in Java ways the solution would be to just use something like in the example below but it seems like this is not possible in C .
class ManagerClass {
private:
// Here seems to be the problem.
std::vector<TemplateClass<?>> templates;
}
Is it possible to do something like that?
Thank you for all answers
CodePudding user response:
If you know all the types that will be stored in the std::vector
at compile time I'd use an std::variant
in such a case.
// This is used for the visitor pattern.
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
// The below line not needed in C 20...
template<class... Ts> overload(Ts...) -> overload<Ts...>;
template<typename T>
struct MyClass { T value; };
using types = std::variant<
MyClass<std::string>,
MyClass<int>,
MyClass<double>>;
int main()
{
std::vector<types> stuff{};
stuff.push_back(MyClass<std::string>{});
stuff.push_back(MyClass<int>{});
stuff.push_back(MyClass<double>{});
for(const auto& v : stuff)
{
if (std::holds_alternative<MyClass<std::string>>(v))
{
std::cout << "Im a string\n";
}
else if (auto* p{std::get_if<MyClass<int>>(&v)})
{
std::cout << "Im an int\n";
}
else
{
auto t = std::get<MyClass<double>>(v);
std::cout << "Im a double\n";
}
// Or you can use the visitor pattern.
std::visit(overload{
[](const MyClass<std::string>& ) { std::cout << "I'm a string\n"; },
[](const MyClass<int>& ) { std::cout << "I'm a int\n"; },
[](const MyClass<double>& ) { std::cout << "I'm a double\n"; },
}, v);
}
}
CodePudding user response:
If you can use C 17, you can use std::any
or std::variant
.
class ManagerClass {
private:
using variant_type = std::variant<
TemplateClass<std::string>,
TemplateClass<int>,
TemplateClass<double> >;
std::vector<variant_type> templates;
};
CodePudding user response:
This is one way of doing it via runtime polymorphishm, which is achieved by function overriding. Function overriding occurs when a derived class has a definition for one of the member functions of the base class. That base function is said to be overridden.
#include <iostream>
#include <vector>
using namespace std;
// Base class declaration
class Base {
public:
virtual void print()
{
cout << "Base" << endl;
}
virtual ~Base(){}
};
// Derived Class 1
class Derived1 : public Base {
public:
void print()
{
cout << "Derived1" << endl;
}
};
// Derived class 2
class Derived2 : public Base {
public:
void print()
{
cout << "Derived2" << endl;
}
};
int main()
{
Base* d1 = new Derived1();
Base* d2 = new Derived2();
vector<Base*> myVec;
myVec.push_back(d1);
myVec.push_back(d2);
for (auto i : myVec) {
i->print();
}
delete d1;
delete d2;
return 0;
}