Х: То, что я хочу сделать:Управление набора векторов шаблонных производных типов
У меня есть типы: BaseType
и DerivedType<int k>
(см код ниже), и мне нужно обрабатывать коллекцию K
векторы производных типов std::vector<DerivedType<k>>
, k = 1...K
. Я хотел бы получить доступ к объектам в этих векторах и выполнить операцию над ними, которая зависит от k
. K
- постоянная времени компиляции. Проблема проиллюстрирована в реализации:
типы определяются как:
#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(); }
И то, что я хочу сделать, это:
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;
}
Я хочу, чтобы избежать повторения кода, так что я необходимо изменить только K
, что является постоянной времени компиляции O(10)
. В идеале, я бы что-то «больше как» это:
// 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
Каждый вектор производных типов содержит O(10^6)
на O(10^9)
объекты. Внутренние петли - самая трудоемкая часть моего приложения, что делает dynamic_cast только опцией для цикла самого внешнего.
Y: то, что я пробовал без успеха.
Я нахожусь в данный момент, изучая шаблон метапрограммирования Абрахама C++, чтобы узнать, могу ли я использовать boost::mpl
. Я также делаю учебники по boost::fusion
, чтобы узнать, могу ли я использовать его. Тем не менее, кривая обучения этих библиотек довольно велика, поэтому я хотел сначала спросить, прежде чем инвестировать неделю во что-то, когда доступно более простое и простое решение.
Моя первая попытка была wrapp мои векторы std::vector<DerivedType<k>>
такое, что я могу создать vector<WrappedDerivedTypes*>
, и получить доступ к каждому из отдельных векторов по отдельности в for_each
цикла. Однако в цикле у меня есть серия if(dynamic_cast<std::vector<DerivedType<0>>>(WrappedVector) != 0){ do for_each loop for the derived objects } else if(dynamic_cast...) { do...} ...
, которую я не смог устранить.
Может ли ваша 'функция doSomething' просто взять ссылку на 'BaseType'? Приведенная вами реализация не зависит от параметра шаблона 'k'. – quamrana
В дополнение к тому, что предлагает quamrana: почему бы просто не сделать 'doSomething()' виртуальный метод и явно специализировать его для каждого производного типа? Тогда вы можете просто сохранить ваши k векторы в векторе векторов указателя-to'BaseType'. (Вам понадобится «фабричный метод», чтобы сначала построить каждый «DerivedType», но после этого их можно обрабатывать равномерно с помощью родительского типа «BaseType».) Как бы то ни было, я не вижу, что получается, DerivedType 'происходит от' BaseType'. –