Reputation: 2179
I am trying to have a container of template elements but it's not compiling because the first argument is not given
So I want to put the following class in a std::map
template <typename T>
class TemplateParam
{
ITemplateParam<T> param_;
public:
TemplateParam(T value)
{
if (sizeof(value) >= sizeof(void*))
param_ = ptrTemplateParam<T>(value);
else
param_ = cpyTemplateParam<T>(value);
}
const T &getParam() const { return param_.getParam(); }
};
ITemplateParam
template <typename U>
class ITemplateParam
{
public:
virtual ~ITemplateParam(){}
virtual const U& getParam() const = 0;
};
I think I understand why I can't put elements of different sizes in a container, it's why I used ptrTemplateParam
and cpyTemplateParam
. (I have also tried with the shared_ptr)
Do you have any idea how can I resolve my problem
I can use boost library
I have looked at this link but I don't know how can I declare the getter.
Edit:
Thanks to your answer I am able to store it in a map but I'm not able to insert an element in the map and I have to use void*
So I have changed my class to:
class ITemplateParam
{
public:
virtual ~ITemplateParam(){}
virtual const void *getParam() const = 0;
};
template <typename U>
class ptrTemplateParam : public ITemplateParam
{
U param_;
public:
ptrTemplateParam(U & param) : param_(param) {}
virtual const void *getParam() const { return param_; }
};
class TemplateParam
{
std::shared_ptr<ITemplateParam> param_;
public:
template <typename T>
TemplateParam(T value): param_(ptrTemplateParam<T>(value))
{
}
const void *getParam() const { return param_->getParam();}
};
and I try to do
std::map<std::string, TemplateParam> m_;
m_["integer"] = TemplateParam(5);
Edit2 boost::any was the solution
Upvotes: 1
Views: 187
Reputation: 10979
If you need to have a container that contains elements of different type then you have basically 3 ways:
It is unclear from your question what would be best for you.
Upvotes: 3
Reputation: 688
IMHO, if you want to put different items in the same container, you should consider using Boost.Variant. This is not a direct answer to your actual example here, but I found this pattern very useful for this category of problems. You avoid using pointers and enforcing inheritance in an elegant way.
class A {};
class B {};
typedef boost::variant<A, B> item_t;
...
vector<item_t> my_container;
Upvotes: 2