steveo225
steveo225

Reputation: 11892

Non-templated container that can hold anything

I have a small framework for working with threads. The main part is an object that is basically a mutex controlled std::queue that one thread pushes onto, and the other thread pops from.

This class cannot be templated, because the types of objects can vary in a single run. Currently, I created a dumb class:

class Object {
public:
    Object(){}
    virtual ~Object(){}
};

Any object that is to flow from thread to thread via this class must inherit from Object as it is what the std::queue holds. This works well, but I imagine there must be a better approach as this approach requires inheritance and many calls to dynamic_cast. Any ideas?

EDIT The pointers in this case are also smart pointers, so type information is important to be maintained.

Upvotes: 3

Views: 228

Answers (4)

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361762

Use std::queue<boost::any>. It will hold objects of any type.

And to get the object, you've to use a special cast function provided by boost itself:

Upvotes: 6

James Kanze
James Kanze

Reputation: 154037

The question is how the types can vary. You certainly have to have some constraints on what goes into the container. Why are the objects put into the container? Based on this, you should be able to design are reasonable abstract base class which would allow virtual functions to be used for the dispatching, rather than deriving from an artificial Object with no interface. (Depending on the purpose of the container is, some variant of the visitor pattern may be necessary. Thus, for example, a message queue might contain a virtual function processMessage( Base* ), whose concrete implementations do nothing but call different member functions of Base.)

Upvotes: 1

Maister
Maister

Reputation: 5054

You might want to look into boost::any if you want to be more typesafe.

Upvotes: 1

Adam Rosenfield
Adam Rosenfield

Reputation: 400642

Use a void* in your container for a "pointer to unknown type" (or const void* if the objects are immutable). It still requires casting (and therefore type information from some other side channel), but you really don't have any other options if you want to avoid templates and inheritance.

Upvotes: 1

Related Questions