How to convert a tuple to a`void`pointer vector?

Asked

Viewed 104 times

1

I have tuples with objects that can have different types. How I would generalize the following code:

#include <iostream>

std::vector<void *> to_vector(std::tuple<int, double, std::string> x)
{
    std::vector<void *> out;
    out.push_back((void *)new int(std::get<0>(x)));
    out.push_back((void *)new double(std::get<1>(x)));
    out.push_back((void *)new std::string(std::get<2>(x)));
    return out;
}

int main()
{
    std::tuple<int, double, std::string> x = {1, 2, "hi"};
    std::vector<void *> v = to_vector(x);

    for (auto i : v)
    {
        std::cout << i << std::endl;
    }
}

That is, I would like the function to_vector could receive any tuple and return an array of pointers without explicitly writing all the push_backs. I imagine this is possible using templates and some variation of what was done here, but I could not at all.

  • you’ve already taken a look therein? I haven’t been able to test it yet, but maybe it’ll help you.

  • the problem is that apparently this assumes that all elements of the tuple have the same type, which does not happen in my case.

1 answer

3


If you can use C++17, use Parameter pack with fold Expressions and std::apply:

#include <iostream>
#include <vector>
#include <tuple>
#include <string>
#include <utility>

template<class ... T>
std::vector<void *> to_vector(const std::tuple<T...>& x) {
    std::vector<void*> out;
    std::apply([&out](auto&&... args) {
        out.reserve(sizeof...(args));
        ([&](){
            using elem_type_no_ref = std::remove_reference_t<decltype(args)>;
            using elem_type_no_const = std::remove_const_t<elem_type_no_ref>;
            out.push_back(new elem_type_no_const(std::forward<elem_type_no_ref>(args)));
        }(), ...);
    }, x);
    return out;
}

int main()
{
    std::string t {"test"};
    std::string t2 {"test-move"};
    std::tuple<int, double, std::string&, int, std::string&&> x = {1, 3.14, t, 9, std::move(t2)};
    std::vector<void *> v = to_vector(x);

    int i = 0;
    std::apply([&](auto&&... args) {
        ((std::cout << *(std::remove_reference_t<decltype(args)>*)v[i++] << std::endl), ...);
    }, x);
}

Don’t forget to divert resources.

  • my God what a beautiful thing, thank you so much for introducing me to this world

Browser other questions tagged

You are not signed in. Login or sign up in order to post.