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

Нещодавно вирішив написати свою бібліотеку для роботи з 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

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.