Trouble combining GP and OOP concepts - c++

I have a class with a templated member function:
class Person
{
template <typename TItem>
void DoSomething(TItem item)
{
item.Action();
}
};
This allows me to pass any item with an Action member function, and the person will perform that action with the item. So I could do:
Person person;
BaseballBat bat;
person.DoSomething(bat);
This structure allows me to call functions with any type of object. However, if I want to store any type of object, I'd have to template the class:
template <TItem>
class Person
{
public:
void DoSomething()
{
this->Item.Action();
}
void SetItem(TItem item)
{
this->Item = item;
}
private:
TItem Item;
};
Person<BaseballBat> person;
BaseballBat bat;
person.SetItem(&bat);
person.DoSomething();
This is annoying because I'd have to re-instantiate the Person class to change the type of object.
Alternatively, I could derive the item from a parent class:
class Person
{
public:
void DoSomething()
{
this->Item.Action();
}
void SetItem(TItem* item)
{
this->Item = item;
}
private:
ParentItem* Item;
};
class ParentItem{};
class BaseballBat : public ParentItem
{}
Person person;
BaseballBat bat;
person.SetItem(&bat);
person.DoSomething();
This is annoying because I have to maintain the inheritance structure for all Items (which seems very "non-GP").
The problem really comes when I have multiple layers of "objects that contain objects" - that is, I'd have to "pass along" the function template arguments from a very "top level" call down to the contained classes:
class BaseballBat
{
void DoAction();
};
class Child
{
template <typename TItem>
void DoAction(TItem item)
{
item.DoAction();
}
};
class Person
{
Child child;
// This is annoying to have to pass the item to the person, who then has to pass it to the child. I'd rather "give" the child an Item, then just be able to call child.DoAction(), where the Person doesn't know anything about the item.
template <typename TItem>
void PlayWithChild(TItem item)
{
child.DoAction(item);
}
}
Can anyone comment about how to correctly mix these two ideas of function templates and storing objects as member data? (The above are just cheesy examples to try to demonstrate - if they don't make sense or you have better examples, I'm all ears :) ).
--------- Edit ---------
Maybe a better example is a simplification of my real case.
I have a class Matcher that has a member function:
template<typename TDistanceFunctor, typename TPropagationFunctor>
void Matcher::Compute(TDistanceFunctor distanceFunctor, TPropagationFunctor propagationFunctor);
Then I have another class, ImageAlgorithm, that uses a Matcher:
template<typename TMatcher>
void ImageAlgorithm::Compute(TMatcher matcher)
{
matcher.Compute(...); // How do I get the DistanceFunctor and the PropagationFunctor here?
}
I want to call these things like:
Matcher myMatcher;
.... Setup matcher (how?) ...
ImageAlgorithm algorithm;
algorithm.Compute(myMatcher);
I don't know how to "pass through" the DistanceFunctor and PropagationFunctor through the ImageAlgorithm object so it can get to the Matcher object inside of the ImageAlgorithm::Compute call. Of course I could template Matcher on TDistanceFunctor and store a TDistanceFunctor as a member variable, but then later I can't change the distance functor that the matcher uses to a different type of distance functor.

You can try using boost::any to hold your type-variant members.
From the overview:
The boost::any class (...) supports copying of any value type and safe checked extraction of that value strictly against its type.
EDIT
You're right that invocation of the stored functor with boost any would be problematic. So I suggest another solution:
Use std::function (or boost::function) to wrap your functors. That way Matcher can hold function objects of the relevant syntax (e.g. no parameters), and does not need to be templated over the functors types.
The function object already does the combination between OO (at least in some sense) and GP for you.

Related

C++ Map with template with different types

I am using Google Protobuf and I want to use the created classes in a 'base' class. I created a template for this, but I want to add references to other classes within it (which can be a reference to 1 class, or more classes). Example:
template<typename T>
class SomeClass
{
public:
std::shared_ptr<T> get(int id)
{
// Of course this contains more checks, but that is not important for the example.
items.find(id).second();
}
void add (std::shared_ptr<T> item)
{
items.emplace(item.id(), item)
}
private:
std::map<int, T> items;
}
This works ok. But now I want to add a map or vector or whtvr with SomeClass items in it, but the T here is different every time. So I want to be able to do:
SomeClass<Person> person;
SomeClass<Animal> animal;
SomeClass<Plant> plant;
person.add(animal);
person.add(plant);
The add function should look something like this:
private:
std::vector<SomeClass<???>> someContainer;
public:
void add(SomeClass<???> item)
{
someContainer.push_back(item);
}
Maybe good to know: T is a google protobuf Message.
I tried to add a class where SomeClass derives from. However, when you want to do the 'get', you need to have T as well for the base class. And then it starts over again.
Is there a way to do this?

Array of inherited classes

I have an Inventory class in which I would like to make an array with objects from the classes Sword, Shield and Potion.
class Inventory {
public:
Inventory();
~Inventory();
virtual void add();
Inventory** getinvent();
void setinvent(Inventory** new_inventory);
int getsize();
void setsize(int new_size);
private:
Inventory** inventory;
int invent_size;
};
Inventory::Inventory() {
inventory = new Inventory*[1];
invent_size = 1;
}
class Sword : public Inventory {
public:
Sword(int strength);
~Sword();
void add();
private:
int strength;
Sword* sword;
};
Sword::Sword(int strength) {
this->strength = strength;
sword = this;
}
void Sword::add() {
setsize(getsize() + 1);
Inventory** new_invent = new Inventory*[getsize()];
for (int i = 0; i < getsize() - 1; i++) {
new_invent[i] = getinvent()[i];
}
new_invent[getsize() - 1] = sword;
setinvent(new_invent);
}
The Shield and Potion classes are similar to the Sword class. If I make the following objects in the implementation:
Inventory* inventory = new Inventory();
Sword* sword = new Sword(1);
How do I now add this sword to this specific inventory? I don't think sword->add(); would work, since sword doesn't know it's inherited from inventory. Is this correct?
I tried to make the add() method virtual, since it has to work for sword, shield and potion objects.
Using dynamic polymorphism, we can create an abstract class Item, which describes the functionality an item has in an inventory. It's useful because, with such class, it's possible to manage items we don't know about, we only know that they will behave like one.
class Item
{
public:
virtual ~Item() = default;
virtual const char* description() const = 0;
};
Going further, all other items (swords, bottles etc) can inherit from this class, thus giving them the characteristic of being an item:
class Sword: public Item
{
public:
Sword() = default;
virtual ~Sword() = default;
const char* description() const override
{ return "Sword"; }
};
In the description method, it's overridden the Item::description abstract one, so whenever you call .description from an instance of Sword, you'll have the "Sword" string returned. For example:
Sword sword{};
Item& item = sword;
std::puts(item.description()); // prints the "Sword" string.
It's now simpler to store items, we just have to use a vector of them: std::vector<std::unique_ptr<Item>>.
#include <vector>
#include <memory>
std::vector<std::unique_ptr<Item>> inventory{};
inventory.emplace_back(std::make_unique<Sword>());
But why can't we have an std::vector<Item>? Simply because it's not possible to construct an Item from a Sword. Actually, it's not possible to even construct an Item, because it has abstract methods (i.e. they are there only to describe the method's prototype, not its definition/implementation).
std::unique_ptr is one of the few C++ smart pointers, it's there so we don't have to manually handle allocations. Using new and delete in your code can result in memory leaks and disasters because of the programmer's distraction, so a smart pointer makes this problem inexistent.
Finally, in order to have an item back, you may simply down-cast the thing back to a Sword:
const auto& item = inventory[0]; // item is `const std::unique_ptr<Item>&`
puts(item->description()); // prints "Sword"
puts(dynamic_cast<Sword*>(item.get())->description()); // also prints "Sword"
The latter (using dynamic_cast) will create a transformed pointer to that first item, from item.get() method, but in the form of Sword*. You'll want to do this if there is a method or data member from Sword that isn't common to Item. For example, if you had something like "int sword_power`, you'd do this:
auto sword = dynamic_cast<Sword*>(item.get());
if (sword != nullptr)
{
std::printf("sword power: %d\n", sword->sword_power);
}
Of course, checking if the cast was successful is optional, but doing that prevents your code from performing undefined behavior (in case the cast fails and a null pointer is returned).
There's still another way of doing this system (not prior to C++17), using the new library tool std::variant.
Basically, a variant lets you have one of many different types at a time. Different from tuples, that lets you have many different types (like a struct), a variant will only let one value from one type at a time. For better understanding it, here's how it works:
#include <variant> // C++17
struct Sword {};
struct Bottle {};
std::variant<Sword, Bottle> item = Sword{};
Like a std::tuple, a variant will have its possible types in the template parameters as arguments (i.e. the Sword and Bottle types are part of item's whole type). This way, you can have either a sword OR a bottle at a time, but never both at the same time. Let's implement our inventory with that new functionality. First we have to change our classes a bit:
class Sword
{
public:
int power;
Sword() = default;
const char* description() const
{ return "Sword"; }
};
class Bottle
{
public:
bool empty;
Bottle() = default;
const char* description() const
{ return "Bottle"; }
};
We removed the need of virtual methods and dynamic polymorphism, and you'll further see that we won't need dynamic allocation anymore, as std::variant is required to work in the stack (which means program will be faster also (maybe)).
Now, for the Item concept, we make an alias of variant with our classes:
using Item = std::variant<Sword, Bottle>;
And we can use this with a vector too:
std::vector<Item> inventory{};
inventory.emplace_back(Sword{});
inventory.emplace_back(Bottle{});
There are a few ways of interacting with those items in case you need them back. One is to use std::holds_alternative:
auto& item = inventory[0];
if (std::holds_alternative<Sword>(item))
{
auto& sword = std::get<Sword>(item);
sword.power = 42;
std::printf("%s: %d\n", sword.description(), sword.power);
}
It checks whether an object of a variant is holding the value of a giving type. In this case, we checked for Sword. Then, if there's a sword in there, we get the value using std::get<>, which returns a reference to our item as a Sword.
Another way of getting access of the real object is by using std::visit. Simply put: visitors are objects that behave like a function with overloads. You can call a visitor just like a function. In order to make a visitor, we can either use a struct with overloaded operator()s, or lambdas. Here's the first approach:
struct VisitItem
{
void operator() (Sword& sword) const
{
std::printf("%s: %d\n", sword.description(), sword.power);
}
void operator() (Bottle& bottle) const
{
std::printf("%s: %s\n", bottle.description(),
bottle.empty? "empty" : "full");
}
};
auto& item = inventory[0];
std::visit(VisitItem{}, item); // we give an instance of VisitItem for std::visit, and the item itself.
Here, std::visit will call the correct operator() for the current object inside the variant (i.e. the item). If item is holding a Sword, so operator() (Sword&) will be called.
The other approach is to make overloaded lambdas. It's a bit complex yet, as we don't have a library tool for that, but with C++17 it is actually easier to implement it:
template <typename... Ts>
struct overload : Ts...
{
using Ts::operator()...;
template <typename... TTs>
constexpr explicit overload(TTs&&... tts) noexcept
: Ts{std::forward<TTs>(tts)}...
{
}
};
template <typename... Ts>
explicit overload(Ts&&...) -> overload<std::decay_t<Ts>...>;
And then use it like so:
auto& item = inventory[0];
auto visitor = overload(
[] (Sword& s) { std::printf("power: %d\n", s.power); },
[] (Bottle& b) { std::printf("%s\n", b.empty? "empty" : "full"); }
);
std::visit(visitor, item);
If you want to understand what's happening in the overload struct, it's inheriting from all lambdas you're giving it, and bringing the operator() overloads into overload lookup (because function overloads from base classes aren't considered as candidates, so you have to using overload). The line after the overload struct is a user-defined deduction guide, which means you can change the template arguments of a template struct based on the constructor.
It seems that you accidentally assigned the same name to two very different classes.
One class is "Item" - and "Sword" extends it.
class Sword: public Item {...};
Another class is "Inventory" - it represents a list of items.
class Inventory
{
void add(Item*) {...}
...
Item** inventory;
};
Then you should make sure you only have one inventory, not one inventory per item. Adding stuff to this inventory should then be easy.
Inventory* inventory = new Inventory();
Sword* sword = new Sword(1);
inventory->add(sword);
Note: You should avoid using new and delete. Use standard containers (std::vector) where possible. In addition, use smart pointers (std::unique_ptr) where possible. Instead of pointer-to-pointer, use a list of smart pointers:
Item** inventory; // works, but not so good
std::vector<std::unique_ptr<Item>>; // better
This is a coding-practice advice. It doesn't affect what the code really does, it's only there to reduce confusion (e.g. where to put delete, which corresponds to new).

Derived class template

I have some question on derived class templates. I have base and derived class templates like this:
// This is base class
class CParameter {
public:
CParameter(std::string name) : name(name) {}
// virtual ~CParameter() {} // deleted for good design:)
public:
std::string name;
};
...
// This is derived class
template <typename T>
class CTemplateParameter : public CParameter {
public:
CTemplateParameter(std::string name) : CParameter(name) {}
public:
T parameter;
};
and I declare some type parameters the push them to base class vector
//Base class parameters
std::vector<CParameter*> parameters; // !
CTemplateParameter<CMatrix4<float>> mat4;
CTemplateParameter<CVector3<float>> vec3;
CTemplateParameter<float> flt;
parameters.push_back(mat4);
parameters.push_back(vec3);
parameters.push_back(flt);
I have template SetParameter function:
// This method moved to CParameter base class
template <typename T>
bool SetParameter(const CTemplateParameter<T>& param) {
// switch(typeof(T)) {
// set parameter
if (std::is_same<T, int>::value)
// gLUniform1i(...)
else if (std::is_same<T, CMatrix4<float>>::value)
// glUniformMatrix4fv(..)
...
}
So my questions:
1) How to set all parameter individual?
// Notice this function is not template
void SetAll() {
for each parameter
SetParameter(parameter[i])
}
2) Without enum, can I get type of parameter and create a type in run time? Like:
Pseudo code:
//get type of parameter[i]
//create a parameter from
T type = GetTypeofParameter(parameter[i]);
CTemplateParameter<type> newType;
3) Can i get a derived class type like this or how to cast?
CTemplateParameter<void*>* p = dynamic_cast<CTemplateParameter<void*>>(parameters[i]);
Thanks so much.
My comments seem to have pushed ADesignersEncyclopedia away from a template/virtual mix but not toward a practical alternative. The original question doesn't give enough info to decide whether there is a practical alternative. Lacking such a practical alternative, do the virtual/template mix correctly (with CRTP) rather than reject it entirely:
In your target class, you want setParameter in two forms, neither of which is a template. The first form dispatches to the setParameter inside the parameter class, which dispatches back to the second form in the target class:
bool SetParameter(const CParameter& param) {
return param.SetParameter( *this );
}
The second form is overloaded on the value type:
bool SetParameter(int value) {
// whatever
}
bool SetParameter(CMatrix4<float> const& value) {
// whatever
}
...
In your parameter base class, you want SetParameter pure virtual
class CParameter
{
...
virtual bool SetParameter( TargetType& ) const = 0;
...
};
Then you need a CRTP base class, which should be derived from your simple base class:
template<class ActualType>
class CRTPParameter : public CParameter
{
CRTPParameter(std::string name) : CParameter(name) {}
ActualType* This() {return static_cast<ActualType*>(this); }
ActualType const* This() const {return static_cast<ActualType const*>(this); }
// various things including
ActualType* clone() const { return new ActualType( *This() ); }
bool SetParameter( TargetType& target ) const
{ return target.SetParameter( This()->parameter ); }
};
Then your template class derives from your CRTP class
template <typename T>
class CTemplateParameter : public CRTPParameter<CTemplateParameter<T> > {
public:
typedef CRTPParameter<CTemplateParameter<T> super;
CTemplateParameter(std::string name) : super(name) {}
If everything else is simple enough, then the whole CRTP scheme might be overkill and you could just move clone and SetParameter from CRTPParameter to CTemplateParameter and go back to not having CRTPParameter.
But in my experience with such structures, things soon get messy in CTemplateParameter in ways that a best dealt with by the extra layer.
1/
You should define setParameter in Cparameter as an abstract method, and implement it in your template class.
2/
I suggest to use a clone(or a factory) method, defined as I suggested in 1/. In this method you can copy(or create) your object then define it.
3/
No. You can't cast CtemplateParameter<float> to CtemplateParameter<void*>
1) How to set all parameter individual?
You can't iterate and set the value for all of them, unless you know the type. And put a huge amount of dynamic_cast would not be the solution either as it is not scalable.
One solution would be to keep a map of std::function. These function would not take any parameter and return nothing. They will set the parameter with the right values. Pushing into the vector would be like this:
std::map<CParameter*, std::function<void()>> mySets;
// ...
mySets.emplace(&parameter, [ObjectThatGiveMeNext, &parameter]() {
parameter.setParameter(ObjectThatGiveMeNext.get());
});
Even if you contain the parameter, it is not your main container for parameters. It is only to keep track of which parameter is associated to which function.
The ideal would be to create this function when you create the parameter, because you know the type of the parameter there.
Another solution would be to create a virtual function updateValue that would call setParameter with this.
2) Without enum, can I get type of parameter and create a type in run time?
That is not really possible it's a context where you don't know the type, so you must either know the type (a switch case) or rely on polymorphic behaviour. I think the best here is to rely on polymorphic behaviour.
I would add a virtual function clone for that. Maybe not the famous straight clone function, but a clone function that return both the parameter and the function to set it's value. Something a bit like that:
std::tuple<std::unique_ptr<CParameter>, std::function<void()>> clone();
Consider a typedef or using in this case as the type is loooooong.
3) Can i get a derived class type like this or how to cast?
No you can't. You would need to convert the instance of your class to another, not related type. I would not do that. Instead, keep your code that deal with your specific derived class where you explicitely know the type and keep the generic code generic (eg: not trying to know the type). This is the best advice I can tell you right now.

C++11 Pure virtual 'templated' return type in non-templated base class

Here's what I'm trying to accomplish:
I'm trying to created a linked list of various types. In order to accomplish this, I figured polymorphism would be a great way to go about.
I have two classes, AttributeBase and Attribute. AttributeBase is used by AttributeSet, which just stores the start and end points of the linked list of Attribute<T>'s (as AttributeBase*'s) and does modification on the list. AttributeBase is a base class of Attribute<T> that is only in the design for the sake of making generic pointers. Attribute<T>, of course, is the specific type of AttributeBase where the actual value is stored. The main data of each Attribute<T> is an inherited string (the attribute's name, or 'key' if you will) and a value of type T.
So, thus far I have (simplified):
class AttributeBase
{
public:
AttributeBase() = delete;
AttributeBase* GetNext() { return next; };
AttributeBase* GetPrev() { return prev; };
std::string GetName() { return name; };
//Sometimes I need to get/set the value stored in a derived class
//But, how would I define the function here since the return
//type is of type T as defined in Attribute?
virtual ???? GetValue = 0;
virtual void SetValue(????) = 0;
friend class AttributeSet;
private:
AttributeBase* next = nullptr;
AttributeBase* prev = nullptr;
std::string name;
};
template <class T>
class Attribute : public AttributeBase
{
public:
Attribute( std::string _name, T _value ){ name = _name; value = _value };
T GetValue(){ return value; };
void Setvalue(T){ value = T; };
private:
T value;
};
class AttributeSet
{
public:
template <class T>
void Add(std::string,T); //Add an Attribute<T>(std::string,T) to the list
void Delete(std::string);
bool Contains(std::string _name); //Scan the list to determine if an
//attribute with name of _name exists
template <class T>
T Get(std::string); //Scan the list for 'name' and return
//AttributeBase*->GetValue()
private:
AttributeBase* start = nullptr;
AttributeBase* end = nullptr;
}
Since I tried to keep AttributeBase generic and non-templated (to avoid strongly-typed start and end pointers in AttributeSet), this brings up a problem. How do I specify an as-of-yet unspecified return type for the virtual function BaseAttribute::GetValue(). I first tried using auto, got a compile error.
Being as no instances of AttributeBase are ever actually created (and the default constructor deleted) I figured it would be possible to leave out GetValue and define it in the derived class. However, if I try *AttributeBase->GetValue() it errors out since GetValue() isn't defined in AttributeBase, only the subclasses. You would think the compiler would know that the pointer has to point to a derived class (the only derived type) since AttributeBase cannot be directly constructed.
So, in order to use GetValue() I have to know the type of the previous value ahead of time to be able to cast the AttributeBase* to an Attribute*. This would be trivial if AttributeBase itself were templated and contained a value T type. I could then just access AttributeBase*->type to determine the type of pointer I need to cast. However, like I said, templating AttributeBase destroys the intended use of the object.
More than likely, I'm going about this in a completely wrong way (yet again). But at this point I am stuck for ideas. Any help would be appreciated!
So a truly general solution doesn't exist. You just can't get any arbitrary type from a base class because all your overrides of your base class virtual function have to have the same return type.
That leaves you two options.
First, you can decide in advance that you're going to have your list hold any object that derives from some common base type. This will severely limit what you can put into your list, but at least you have full freedom with those objects once they're there.
Second, depending on what you want to actually do with the objects once they're in your list, you can look at the new Boost.TypeErasure library. If all you need to do with list is, say, output them all, or some either small amount of operations, this can help you get there.
Since the signatures of GetValue and SetValue depend on a type, they need to be templates. But they can be template members without requiring a class template.
class AttributeBase
{
public:
template <typename T> T GetValue() const;
template <typename T> void SetValue(T);
//...
};
template <typename T>
T AttributeBase::GetValue() const
{
return dynamic_cast<Attribute<T>&>(*this).GetValue();
}
template <typename T>
void AttributeBase::SetValue(T val)
{
dynamic_cast<Attribute<T>&>(*this).SetValue(val);
}
template <typename T>
T AttributeSet::Get(std::string const& name) const
{
// (assuming a private helper method Find().)
const AttributeBase* attr = Find(name);
if ( !attr )
throw std::invalid_argument("attribute not in set");
return attr->GetValue<T>();
}
One gotcha, though: these functions will all throw an exception if you happen to use the wrong type. And SetValue might automatically deduce its template argument, and might do so incorrectly. For example, if a is a AttributeBase& reference which is really an Attribute<long int>, then a.SetValue(1) is the same as a.SetValue<int>(1), which will throw. The correct expression would be a.SetValue<long int>(1) (or a.SetValue(1L), but I'd prefer the explicit template argument).

Best way for derived classes to carry different data types in C++

What is the most elegant way to provide an interface in C++ that accepts derived class types that carry with them different data type members that then need to be retrieved later. The example below illustrates this where the Container class provides methods to "post" an Item that will be some kind of derived variant of BaseItem. Later on I want to get the derived Item back and extract its value.
The main thing I want is for the Container interface (post and receive) to stay the same in the future while allowing different "Item" derived types to be defined and "passed" through it. Would template be better for this somehow; I'd rather not use RTTI. Maybe there is some simple, elegant answer to this, but right now I'm struggling to think of it.
class ItemBase {
// common methods
};
class ItemInt : public ItemBase
{
private:
int dat;
public:
int get() { return dat; }
};
class ItemDouble : public ItemBase
{
private:
double dat;
public:
double get() { return dat; }
};
class Container {
public:
void post(int postHandle, ItemBase *e);
ItemBase* receive(int handle); // Returns the associated Item
};
int main()
{
ItemInt *ii = new IntItem(5);
Container c;
c.post(1, ii);
ItemInt *jj = c.receive(1);
int val = jj->get(); // want the value 5 out of the IntItem
}
This is definitely a candidate for generic programming, rather than inheritance. Remember, generics (templates) are ideal when you want identical handling for different data types. Your ItemInt and ItemDouble classes violate OO design principles (the get() method returns different data types depending on what the actual subtype is). Generic programming is built for that. The only other answer would be a tagged data type, and I personally avoid those like the plague.
How about?
template<typename T>
class Item
{
private:
T dat;
public:
T get() { return dat; }
};
class Container {
public:
template<typename T>
void post(int postHandle, Item<T> *e);
template<typename T>
Item<T>* receive(int handle); // Returns the associated Item
};
int main()
{
Item<int> *ii = new Item<int>(5);
Container c;
c.post(1, ii);
Item<int> *jj = c.receive<int>(1);
int val = jj->get(); // want the value 5 out of the IntItem
}
Your Container class looks suspiciously like a std::map. It looks to me like your ItemBase class is just a different name for "Object", the universal base class, which I think is not much different from (or better than) void*. I would avoid trying to contain items of different type in a single container. If your design seems to call for doing so, I'd rethink your design.
A pure template approach doesn't work because you apparently want to have mixed types in your container. You could work with something like Boost's any although I think you need to restore the actual. What I think is called for in this case is a base class exposing the type-independent and virtual methods plus a templatized derived class to hold the actual items:
class Base {
public:
virtual ~Base() {}
virtual void post() = 0;
};
template <typename T>
class Item: public Base {
public:
Item(T const& value): value_(value) {}
void post() { std::cout << "posting " << this->value_ << "\n"; }
private:
T value_;
};
This approach avoids the need to write any derived Item class for another value type. To make creation of these beast easier you probably want to create a suitable creation function as well, e.g.
template <typename T>
std::unique_ptr<Base> make_item(T const& value) {
return std::unique_ptr<Base>(new Item<T>(value));
}
A std::unique_ptr<Base> is returned to make sure that the allocated object is released (if you don't use C++2011 you can used std::auto_ptr<T> instead). This type can easily be converted to other pointer types, e.g. to a std::shared_ptr<Base> which is a better suited to be put into a container.