У меня есть фильтр, который должен работать на произвольных тензорах.Для моего случая достаточно, когда фильтр работает с тензорами ранга 1,2 и 3, которые являются списками, матрицами и 3d-матрицами или объемами соответственно.Кроме того, фильтр может применяться в каждом возможном направлении.Для списка это только одно, для матриц существует 2 возможных направления (а именно для направления X и Y), а для томов существует 3 возможных направления.
Прежде чем углубляться в детали, позвольте мне спроситьпервый вопрос: У меня все в порядке с фильтром, или я забыл что-то важное, что может доставить мне неприятности позже?Я не новичок в шаблонах C ++, но я не чувствую себя как рыба в воде.Можно ли сжимать этот макет дальше (может быть, есть способ обхода фиктивных XDirection
классов или более коротких Type2Type
)?
Основная процедура фильтра для каждого ранга тензора и для каждого направлениятот же самый.Здесь всего несколько строк кода, функция callKernel
, которые отличаются.Чтобы заставить перегруженный operator()
вызвать правильную функцию callKernel
, это единственная интересная часть в коде ниже.Поскольку частичная специализация для шаблонов не работает для методов класса, вы можете преобразовать аргументы шаблона в реальный тип класса и передать его в качестве фиктивного аргумента в callKernel
.
Следующий код - это макет доУровень 2. Он компилируется с g++
и может быть испытан.
template <class DataType, int Rank>
class Tensor { };
class XDirection;
class YDirection;
template <class TensorType, class Direction>
struct Type2Type {
typedef TensorType TT;
typedef Direction D;
};
template <class TensorType, class Direction>
struct Filter {
Filter(const TensorType &t){}
TensorType operator()(){
/* much code here */
callKernel(Type2Type<TensorType,Direction>());
/* more code */
TensorType result;
return result;
}
void callKernel(Type2Type<Tensor<double,1>, XDirection>) {}
void callKernel(Type2Type<Tensor<double,2>, XDirection>) {}
void callKernel(Type2Type<Tensor<double,2>, YDirection>) {}
};
int main(void) {
Tensor<double, 2> rank_two_tensor;
Filter<Tensor<double,2>,XDirection> f(rank_two_tensor);
f();
}
Позвольте мне добавить несколько важных вещей: необходимо, чтобы логика фильтра была в operator()
, потому что вы видите здесьсобирается использовать с Intel Threading Building Blocks , которые требуют эту структуру.Очень важно, чтобы callKernel
был встроен.Из всего, что я знаю, так и должно быть.
Заранее благодарим за любой полезный и критический комментарий.