如何编写可变参数模板 class?
How can I write a variadic template class?
根据我的理解,可变参数函数是采用可变数量参数的函数。
现在我想将它应用到一个模板函数,我希望它的构造函数是可变的。我不知道这是否可能以及如何实现。因此,我的问题是:
可能吗?
我该怎么做?
这是我的非可变模板 class。我希望能够有不同数量的占位符参数 T(因此只有 T1,或者 T1、T2 或者 T1 到 T5)。
template<typename T1, typename T2>
class tXmlBase
{
public:
tXmlBase(tXmlDoc* doc, T1 id1);
tXmlBase(tXmlDoc* doc, T1 id1, T2 id2);
virtual ~tXmlBase();
protected:
tXmlDoc* xml_doc;
pugi::xml_node root_node;
pugi::xml_node base_node;
pugi::xml_node parent_node;
T1 identifier1;
T2 identifier2;
int n_childs;
int n_attr;
我读过这篇文章,但我不确定如何将其翻译成我的 class:https://en.cppreference.com/w/cpp/language/parameter_pack
编辑:为了更清楚:
这样做的目的如下:
class 应处理存储在 xml 文件的特定节点内的信息。让我们假设以下 xml 文件结构:
<root>
<node>
<elem id="1">
<low_level_info type="info" content="abc"/>
<low_level_info type="info" content="xyz" />
</elem>
<elem id="2">
...
</elem>
<node>
<node>
...
</node>
</root>
因此,一些节点只是节点,仅通过位于同名节点(此处为“名称”)之前出现后的第二个位置来区分,其他节点通过一个或多个属性(id、内容、类型)。
而且我希望我的 class 能够处理我有不同的方法来区分这些节点。
由于无法创建可变数据成员,您将不得不使用 std::tuple
。剩下的就很简单了:
template<typename... Ts>
class tXmlBase
{
public:
tXmlBase(tXmlDoc* doc, Ts const&... id1);
// if you have no other virtual member, it's better to remove this.
virtual ~tXmlBase();
protected:
tXmlDoc* xml_doc;
pugi::xml_node root_node;
pugi::xml_node base_node;
pugi::xml_node parent_node;
std::tuple<Ts...> identifiers;
int n_childs;
int n_attr;
};
如果你想对所有标识符做一些事情,你可以使用可变参数 lambda 和 std::apply
:
std::apply(
[](auto&... id) {
// expands into (id1.something(), id2.something(), ...)
(id.something(), ...);
},
identifiers
);
根据我的理解,可变参数函数是采用可变数量参数的函数。
现在我想将它应用到一个模板函数,我希望它的构造函数是可变的。我不知道这是否可能以及如何实现。因此,我的问题是: 可能吗? 我该怎么做?
这是我的非可变模板 class。我希望能够有不同数量的占位符参数 T(因此只有 T1,或者 T1、T2 或者 T1 到 T5)。
template<typename T1, typename T2>
class tXmlBase
{
public:
tXmlBase(tXmlDoc* doc, T1 id1);
tXmlBase(tXmlDoc* doc, T1 id1, T2 id2);
virtual ~tXmlBase();
protected:
tXmlDoc* xml_doc;
pugi::xml_node root_node;
pugi::xml_node base_node;
pugi::xml_node parent_node;
T1 identifier1;
T2 identifier2;
int n_childs;
int n_attr;
我读过这篇文章,但我不确定如何将其翻译成我的 class:https://en.cppreference.com/w/cpp/language/parameter_pack
编辑:为了更清楚: 这样做的目的如下: class 应处理存储在 xml 文件的特定节点内的信息。让我们假设以下 xml 文件结构:
<root>
<node>
<elem id="1">
<low_level_info type="info" content="abc"/>
<low_level_info type="info" content="xyz" />
</elem>
<elem id="2">
...
</elem>
<node>
<node>
...
</node>
</root>
因此,一些节点只是节点,仅通过位于同名节点(此处为“名称”)之前出现后的第二个位置来区分,其他节点通过一个或多个属性(id、内容、类型)。
而且我希望我的 class 能够处理我有不同的方法来区分这些节点。
由于无法创建可变数据成员,您将不得不使用 std::tuple
。剩下的就很简单了:
template<typename... Ts>
class tXmlBase
{
public:
tXmlBase(tXmlDoc* doc, Ts const&... id1);
// if you have no other virtual member, it's better to remove this.
virtual ~tXmlBase();
protected:
tXmlDoc* xml_doc;
pugi::xml_node root_node;
pugi::xml_node base_node;
pugi::xml_node parent_node;
std::tuple<Ts...> identifiers;
int n_childs;
int n_attr;
};
如果你想对所有标识符做一些事情,你可以使用可变参数 lambda 和 std::apply
:
std::apply(
[](auto&... id) {
// expands into (id1.something(), id2.something(), ...)
(id.something(), ...);
},
identifiers
);