Search code examples
c++c++11variadic-templates

Template Parameter iteration


Trying to find a simpler way to iterate through a set of Variadic template parameters.

My class holds a tuple of objects represented by the Variadic template parameters. I want to perform a common operation on all the members of the tuple and return an aggregated result.

A simplified Example would be:

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;
       }
};

Here the call to getSize() has to delegate the work getSizeData() to be able to perform the fold expression need to hit all the members of the tuple.

I have avoided using std::get<Kind>(data).getSize() as that would limit the tuple to storing one of each type (unless I am mistaken in someway).

Is there a simpler way of expressing this without using an extra function. ie. do all the work in getSize() rather than delegate the work to a getSizeData()?


Solution

  • You can use std::apply, which unpacks the tuple into a parameter pack, letting you write a fold-expression, like this:

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

    Here's a demo.