Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call variadic templated function with arguments from a std::vector

I need to convert elements of a std::vector to types based on a template parameter and call a function with these parameters. In pseudocode:

template <typename T...>
void foo(std::vector<std::string> v) {
    if (v.size() != sizeof...(T))
        throw std::runtime_error("Bad");

    bar(convert<T0>(v[0]), convert<T1>(v[1]), ..., convert<Tn>(v[n]));
}

My problem is how to obtain the element indices from the parameter pack, I think there will be some kind of a trick using fold expressions, but I can't figure it out.

like image 978
cube Avatar asked Mar 18 '26 20:03

cube


1 Answers

If you know that the number of elements in a vector is equal to the parameter pack size, you can solve this problem by adding one level of indirection:

template<typename... T, std::size_t... is>
void foo_impl(const std::vector<std::string>& v, std::index_sequence<is...>) {
    bar(convert<T>(v[is])...);
}


template<typename... T>
void foo(const std::vector<std::string>& v) {
    assert(v.size() == sizeof...(T));
    foo_impl<T...>(v, std::index_sequence_for<T...>{});
}

The idea here is to expand two packs, Ts... and is..., which have equal sizes, simultaneously.


C++20 solution:

template<typename... T>
void foo(const std::vector<std::string>& v) {
    assert(v.size() == sizeof...(T));

    [&v]<std::size_t... is>(std::index_sequence<is...>) {
        bar(convert<T>(v[is])...);
    }(std::index_sequence_for<T...>{});
}
like image 108
Evg Avatar answered Mar 20 '26 08:03

Evg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!