模板参数迭代
Posted
技术标签:
【中文标题】模板参数迭代【英文标题】:Template Parameter iteration 【发布时间】:2020-09-07 23:28:27 【问题描述】:试图找到一种更简单的方法来遍历一组可变参数模板参数。
我的类包含一个由可变参数模板参数表示的对象元组。我想对元组的所有成员执行一个通用操作并返回一个聚合结果。
一个简化的例子是:
template<typename... Args>
struct Holder
std::tuple<Args> data;
std::size_t getSize() const
return getSizeData(std::make_index_sequence<sizeof...(Args)>());
private:
template<std::size_t... I>
std::size_t getSizeData(std::index_sequence<I...>)
// Initialize
std::size_t result = 0;
// Fold expression to iterate across all members in tuple.
((result += std::get<I>(data).getSize()), ...);
// Aggregated value returned.
return result;
;
这里对getSize()
的调用必须委派getSizeData()
的工作才能执行fold expression
需要命中元组的所有成员。
我已经避免使用std::get<Kind>(data).getSize()
,因为这会限制元组存储每种类型中的一种(除非我在某种程度上弄错了)。
有没有更简单的方法来表达这一点而无需使用额外的功能。 IE。在getSize()
中完成所有工作,而不是将工作委托给getSizeData()
?
【问题讨论】:
我认为没有辅助函数是不可能的。你能用c++17吗?然后你可以在一行中使用std::apply
。
@cigien 在提出问题之前尝试了几个小时。我一问问题就找到std::apply()
。我不应该将 C++11 卡在标签中。是的,我可以在 C++11 之后使用任何东西。如果你回答我会接受你的回答。
好的,Args
中的每个类型都应该有一个getSize
成员函数吗?在这段代码中std::get<I>(data).getSize()
我的意思是?
@cigien:是的;所有Args
都支持相同的“Duck”类型接口。我做了这个简化的例子getSize()
。
【参考方案1】:
您可以使用std::apply
,它将元组解包到一个参数包中,让您编写一个折叠表达式,如下所示:
std::size_t getSize() const
return std::apply([](auto... a)
return (a.getSize() + ...);
, data);
这是demo。
【讨论】:
以上是关于模板参数迭代的主要内容,如果未能解决你的问题,请参考以下文章