The X: What I want to do:
I have the types: BaseType and DerivedType<int k> (see code below), and I need to handle a collection of K vectors of the derived types std::vector<DerivedType<k>>, k = 1...K. I’d like to access the objects in these vectors, and perform an operation on them that depends on k. K is a compile time constant. The problem is illustrated in the implementation:
The types are defined as:
#include <iostream>
#include <algorithm>
struct BaseType { // Interface of the DerivedTypes
virtual void print(){std::cout << "BaseType!" << std::endl; }
};
template< int k >
struct DerivedType : public BaseType {
static const int k_ = k;
// ... function calls templated on k ...
void print(){std::cout << "DerivedType: " << k_ << std::endl;}
};
template< int k >
void doSomething ( DerivedType<k>& object ) { object.print(); }
And what I want to do is:
int main() {
// My collection of vectors of the derived types:
std::vector<DerivedType<0>> derType0(2);
std::vector<DerivedType<1>> derType1(1);
std::vector<DerivedType<2>> derType2(3);
// ... should go to K: std::vector<DerivedType<K>> derTypeK;
// Iterate over the derived objects applying a k-dependent templated function:
std::for_each(begin(derType0),end(derType0),[](DerivedType<0>& object){
doSomething<0>(object);
});
std::for_each(begin(derType1),end(derType1),[](DerivedType<1>& object){
doSomething<1>(object);
});
std::for_each(begin(derType2),end(derType2),[](DerivedType<2>& object){
doSomething<2>(object);
});
return 0;
}
I want to avoid repeating code, such that I only have to change K, which is a compile time constant of O(10). Ideally, I would have something “more like” this:
// Pseudocode: do not try to compile this
create_derived_objects(DerivedType,K)
= std::vector< std::vector<DerivedType<k>>* > my_K_derived_types;
for each vector<DerivedType<k>>* derivedTypes in my my_K_derived_types
for each object in (*derivedTypes)
doSomething<k> on object of type derivedType<k>
// I could also restrict doSomething<k> to the base interface
Each vector of derived types contains O(10^6) to O(10^9) objects. The inner-most loops are the most time consuming part of my application making dynamic_cast only an option for the outer-most loop.
The Y: what I have tryed without succes.
I am at the moment studying the Abrahams C++ Template Metaprogramming book to see if I could use boost::mpl. I am also doing the tutorials on boost::fusion to see if I could use it too. However, the learning curve of these libraries is rather large, so I wanted to ask first before I invest a week in something when a better and simpler solution is available.
My first try was to wrapp my vectors std::vector<DerivedType<k>> such that I can create a vector<WrappedDerivedTypes*>, and access each of the single vectors separately within a for_each loop. However, in the loop I have a series of if(dynamic_cast<std::vector<DerivedType<0>>>(WrappedVector) != 0 ){ do for_each loop for the derived objects } else if( dynamic_cast...) { do...} ... that I wasn’t able to eliminate.
What about a recursive solution based on a generic linked list of vectors, a strategy pattern and a thing that applies strategies recursively through the linked list? (note: see the improved version at the end):
Compile it with a C++11 compiler.
Most probably you’ll find unsatisfactory the fact that building a
lin_vectorrequires a lot of copying, but you can specialize the structure to suit your needs (perhaps substituting thepredwith a pointer or embedding the creation strategy straight into the linked list).EDIT: here there is an improved version which avoids a lot of copying and handles list building and processing in a more coherent and uniform way: