【发布时间】:2020-03-06 14:01:54
【问题描述】:
我有一个模板类,它基本上允许使用 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 版本(在示例中删除)。
我的想法是尝试使用可变参数模板来允许任意数量的参数(我为此选择了 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>() );
}
【问题讨论】:
-
如果你能把你的例子写成minimal reproducible example,那就太好了
-
@NutCracker,我添加了一个使用示例,但不确定 MRE 还需要什么。我可以缩短当前代码以使用不超过 2 个参数,但我认为 3 显示更多我正在处理的内容......编辑:缩短。
-
我的意思是尝试发布一些更容易测试的代码......可能没有 QT 组件
-
@NutCracker,刚刚进行了编辑:P
标签: c++ templates variadic-templates