I'm trying to retrieve values from a tuple of arrays using type information on the function used for processing them. However, type deduction fails for this case due (in part?) to the need to use an identity struct for the typename of the std::function
. Is there a way to restore deduction here?
#include <functional>
#include <iostream>
#include <tuple>
class comp_a
{
public:
static const size_t id = 0;
int val = 0;
};
class comp_b
{
public:
static const size_t id = 1;
int val = 0;
};
class comp_c
{
public:
static const size_t id = 2;
int val = 0;
};
template<size_t size, typename ... Cs>
struct storage
{
template<typename T> struct identity { using type = T; };
template<typename ... Ts>
void get(size_t index, typename identity<std::function<void(Ts& ...)>>::type f)
{
f(std::get<Ts::id>(components)[index] ...);
}
std::tuple<std::array<Cs, size> ...> components;
};
int32_t main()
{
storage<20, comp_a, comp_b, comp_c> storage;
storage.get(2, [](comp_a& a, comp_c& c) { // Doesn't work
// storage.get<comp_a, comp_c>(2, [](comp_a& a, comp_c& c) { // Works
std::cout << a.val << " " << c.val << std::endl;
});
}
I've run across this and this, which seem similar, but I believe my situation is different because I need the variadic types in order to access their traits when retrieving the desired values. As in those examples, the variadic parameters to the function are treated as void:
error: cannot convert 'main()::<lambda(comp_a&, comp_c&)>' to 'storage<20, comp_a, comp_b, comp_c>::identity<std::function<void()> >::type' {aka 'std::function<void()>'}
Would a deduction guide be viable in this situation? The type information seems buried a little deep in the type of the std::function
, and so I'm not sure how I would pull it out in a guide.
A live example is available here.