Короткая заметка про шаблоны и смешание выведение типа и явного его задания

в 7:26, , рубрики: c++, fits, с++11

Намедни решил написать свою библиотеку для работы с FITS-файлами. Да, я знаю, что есть CCFITS, но хотелось изобрести свой велосипед с… сами знаете.

Одна из возможностей формата — данные можно записывать разных типов в массивы разных размерностей.
Очевидный способ это реализовать это определить что-то типа того:

void setBytePix(int value);
void setAxisSize(const std::vector<int> &axis );

Однако данная конструкция не слишком удобна. Простой тестовый пример:

std::vector srcVector;
srcVector.push_back(1024);
srcVector.push_back(1024);
setAxisSize(srcVector);

Если бы вместо std::vector был бы QVector из Qt, все выглядело бы гораздо симпатичнее.

setAxisSize(QVector<int>()<<1024<<1024);

Но в STL этого нет, а сразу завязываться на Qt при всей моей любви к нему не хотелось бы. Решение было найдено вот в таком стиле:

void setAxeSize(int number, int size);
void setNumberDimension(int value);

void setAxisDimensionP(int dimensionNumber, int axisSize){
        setAxeSize(dimensionNumber, axisSize);
}
template<typename ...Arguments> void setAxisDimensionP(int dimensionNumber, int axisSize, Arguments... args){
        setAxeSize(dimensionNumber, axisSize);
        ++dimensionNumber;
        setAxisDimensionP(dimensionNumber, args...);
}
template<typename ...Arguments> void setAxisSize(Arguments... args)
{
<s>         setNumberDimension(sizeof...(args)/sizeof(int));</s> (спсаибо @AxisPod за замечанную ошибку)
         setNumberDimension(sizeof...(args));
         setAxisDimensionP(0, args...);
}

Вот теперь гораздо удобнее:

setAxisSize(1024, 1024);

Следующим возникло желание шаблонизировать и setBytePix. Сказано — сделано:

template <typename T> void setBytePix(){ setBytePix(sizeof(T)*8);}

Аппетиту растут и теперь хочется вызывать не две функцию, а одну. Выкидываем печальные мысли о крокодилах и модернизируем setAxisSize:

template<typename T, typename ...Arguments> void setAxisSize(Arguments... args)
{
     setBytePix<T>();
     setNumberDimension(sizeof...(args));
     setAxisDimensionP(0, args...);
}

А теперь пробуем:

setAxisSize<short>(1392,1032);

Чудо! Оно работает!
P.S. Использовался MinGW с gcc 4.9.1

Автор: DancingOnWater

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js