Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Iterating over a parameter pack

I have a parameter pack args... of vectors of arbitrary types, corresponding to which there is a vector of indices say v = {3,0,5...} having the same size, and order as the number of members of args.... I would like get_tuple to return a tuple of the elements of args... at the indices given by v.

Here’s what I have so far, but I’m stuck trying to iterate over the members of the parameter pack.

template<typename... Args>
auto get_tuple(const std::vector<size_t>& vector, const Args &... args) {
    return std::make_tuple(args[v[0]]...);
}

For example:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

std::vector<std::string> v1 = {"a", "b"};
std::vector<int> v2 = {1,2};
std::vector<size_t> v = {0,1};
auto result = get_tuple(v, v1, v2); // ("a",2) expected

>Solution :

In C++17, you need additional level of indirection to get a pack of indices to get a pack of elements at those indices:

template<typename... Args, std::size_t... Is>
auto get_tuple_impl(const std::vector<std::size_t>& indices,
                    std::index_sequence<Is...>,
                    const Args&... args) {
    return std::make_tuple(args[indices[Is]]...);
}

template<typename... Args>
auto get_tuple(const std::vector<std::size_t>& indices, const Args&... args) {
    return get_tuple_impl(indices, std::index_sequence_for<Args...>(), args...);
}

In C++20, we could you a lambda function with template parameters invoked in-place:

template<typename... Args>
auto get_tuple(const std::vector<std::size_t>& indices, const Args&... args) {
    return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
        return std::make_tuple(args[indices[Is]]...);
    }(std::index_sequence_for<Args...>());
}

You might also want to add an assertion assert(indices.size() == sizeof...(Args)); or use std::array<std::size_t, N> type instead.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading