【问题标题】: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&lt;Kind&gt;(data).getSize(),因为这会限制元组存储每种类型中的一种(除非我在某种程度上弄错了)。

有没有更简单的方法来表达这一点而无需使用额外的功能。 IE。在getSize() 中完成所有工作,而不是将工作委托给getSizeData()

【问题讨论】:

  • 我认为没有辅助函数是不可能的。你能用c++17吗?然后你可以在一行中使用std::apply
  • @cigien 在提出问题之前尝试了几个小时。我一问问题就找到std::apply()。我不应该将 C++11 卡在标签中。是的,我可以在 C++11 之后使用任何东西。如果你回答我会接受你的回答。
  • 好的,Args 中的每个类型都应该有一个getSize 成员函数吗?在这段代码中std::get&lt;I&gt;(data).getSize() 我的意思是?
  • @cigien:是的;所有Args 都支持相同的“Duck”类型接口。我做了这个简化的例子getSize()

标签: c++ c++11 variadic-templates


【解决方案1】:

您可以使用std::apply,它将元组解包到一个参数包中,让您编写一个折叠表达式,如下所示:

std::size_t getSize() const
{
    return std::apply([](auto... a) {
        return (a.getSize() + ...);
    }, data);
}

这是demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多