views:

96

answers:

5

I have a problem with implementing database table library. I have a class Column storing different types.

template <class T>
class Column : iColumn<T>
{ 
... 
}

Table is composed of columns, so I need a collection of them (map with string name as a key and column as value). How shall I implement one collection of all table's columns regardless the template type?

Thanks for any hep.

+1  A: 

I think that boost::any might help you there...

Martin Cote
+4  A: 

Some alternatives:

  1. Boost Fusion http://www.boost.org/doc/libs/1_42_0/libs/fusion/doc/html/index.html

  2. Create a container of Boost any

  3. Make the template class inherit from the same class and store the pointers

  4. As this looks like a database thingy, simply use strings instead of different types.

Viktor Sehr
+1 for mentioning `Fusion`, the "string" argument however I am definitely less in favor of...
Matthieu M.
Thats actually my favourite alternative =)
Viktor Sehr
There is `boost.tuple` as a light weight alternative to `boost.fusion`.
Johannes Schaub - litb
+3  A: 

You should have a common interface.

class Column<T>: public IColumn {
  ...
};

std::map<std::string,IColumn*> columns;
Notinlist
+2  A: 

You can consider using boost::any or boost::variant for canned up solutions. Or you might consider providing a base column type that is the root of the columns hierarchy. It seems as if all columns do have some things in common (probably a name at the very least). All templated column types would derive from it.

I myself, you go the good-old-way and implement a hierarchy with a visitor pattern (double dispatch) for operations that must be performed in the derived elements and are not present in the base of the hierarchy.

David Rodríguez - dribeas
+1 for `boost.variant`. This is certainly more a case for variant instead of any, because the set of types stored seems to be known before.
Johannes Schaub - litb
In fact the order of precedence for the three solutions for me would be: implement a hierarchy (it seems as if columns have things in common), use variant (fixed set of elements and I prefer the visitor mechanism for data manipulation) or any as a last resort (I cannot really think when this would be needed)
David Rodríguez - dribeas
+1  A: 

Your types are, from the C++ type system perspective, completely unrelated. To force a relationship, some kind of type erasure is needed; this may either be a commonly implemented interface or a mechanism like Boost.Any as proposed by others.

However, note that putting different things together isn’t a good design to start with – so you should probably put some though into a meaningful common interface that lets you do all the necessary things without excessive downcasting later on.

Konrad Rudolph