У меня есть шаблонный класс, который в основном позволяет использовать от 0 до 3 различных типов. Эти типы используются в конструкторе для получения значений, которые впоследствии передаются другому конструктору. В настоящее время это выглядит следующим образом (обратите внимание, код сокращен до 2-х параметров и удален ненужный код):
template<class EditorDialog, typename FirstOpt, typename SecondOpt>
class GenericItemDelegateBase {
public:
GenericItemDelegateBase( const FirstOpt &first, const SecondOpt &second ) : first( first ), second( second ) {}
protected:
const FirstOpt first;
const SecondOpt second;
private:
EditorDialog *createEditor() const {
return new EditorDialog( first, second );
}
};
template<class EditorDialog, typename FirstOpt>
class GenericItemDelegateBase<EditorDialog, FirstOpt, void> {
public:
GenericItemDelegateBase( const FirstOpt &first ) : first( first ) {}
protected:
const FirstOpt first;
private:
EditorDialog *createEditor() const {
return new EditorDialog( first );
}
};
template<class EditorDialog>
class GenericItemDelegateBase<EditorDialog, void, void> {
public:
GenericItemDelegateBase() {}
private:
EditorDialog *createEditor() const {
return new EditorDialog();
}
};
template<class EditorDialog, typename FirstOpt = void, typename SecondOpt = void>
class GenericItemDelegate : public GenericItemDelegateBase<EditorDialog, FirstOpt, SecondOpt> {
public:
using Base = GenericItemDelegateBase<EditorDialog, FirstOpt, SecondOpt>;
using Base::Base;
};
Как видите, в коде много дублирования. Мне удалось удалить некоторые из дубликатов, используя наследование и версию Base
, в которой есть часть дубликата кода (например, удалить).
Я думал о том, чтобы попытаться использовать variadi c шаблонов, чтобы разрешить произвольное количество параметров (я выбрал 3 для этого, который работал до сих пор, но возможно в будущем нам может понадобиться больше). Я начал реализовывать это так:
template<class EditorDialog>
class GenericItemDelegate {
GenericItemDelegate() {}
};
template<class EditorDialog, typename type, typename... args>
class GenericItemDelegate : public GenericItemDelegate<EditorDialog, type, args...> {
using Base = GenericItemDelegate<EditorDialog, type, args...>;
GenericItemDelegate( const type &var, args &&... rest ) : Base( std::forward<args>( rest )... ), var( var ) {}
protected:
const type var;
};
Проблема, с которой я столкнулся, заключается в том, что в этой версии я понятия не имею, как реализовать функцию createEditor
. Он должен передать все переменные в конструктор EditorDialog
, что я не уверен, как это сделать (или если это вообще возможно).
QWidget *createEditor() const {
return new EditorDialog( [all vars...] );
}
Я не знаю, что это возможно с Структура наследования, которую я настроил, поскольку, в зависимости от используемого EditorDialog
, он может иметь конструктор, который принимает три параметра, но не тот, который принимает только два.
Я полностью иду по неверному пути? Или это возможно сделать?
Примеры использования:
int main() {
auto a = GenericItemDelegate<int>();
auto b = GenericItemDelegate<int, int>( 3 );
auto c = GenericItemDelegate<std::vector<int>, int>( 3 );
auto d = GenericItemDelegate<std::vector<int>, int, std::allocator<int>>( 3, std::allocator<int>() );
}