Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a tuple of value types from a parameter pack

I need to build a tuple of n types. These n types are value types of n other types. Consider this snippet:

#include <boost/hana.hpp>

namespace hana = boost::hana;

template<class... Types>
class CartesianProduct
{
public:
    CartesianProduct(Types... args) : sets(args...) {}

    hana::tuple<Types...> sets;
    hana::tuple<Types...::value_type> combination; // does not work obviously... but wo can this be done?
};

The application of this is intended like so: I pass this class a parameter pack of containers of possibly different types. The class puts these containers into a tuple sets. The class also has a field combination which is a tuple of as many elements as containers were passed to the class. But the types of the elements are the value types of the different containers.

The class is then intended to lazyly build the cartesian product of the containers passed to it and store the current combination in combination. But how can I actually get to the value types of the containers in a variadic fashion?

like image 854
lo tolmencre Avatar asked Jun 14 '17 06:06

lo tolmencre


1 Answers

It can be done, of course. You just need to declare the pack expansion appropriately.

hane::tuple<typename Types::value_type...> combination; 

Note the required use of the typename specifier. The rule of thumb is to treat the pack name as a single type. The same syntactic/semantic constraints apply, as we must specify that we access a type with the scope resolution operator. Then just tack the pack expansion at the end.

Live Example

#include <vector>
#include <map>
#include <tuple>

template<class... Types>
class CartesianProduct
{
public:
    CartesianProduct(Types... args) : sets(args...) {}

    std::tuple<Types...> sets;
    std::tuple<typename Types::value_type...> combination; 
};


int main() {
    std::vector<int> i;
    std::map<int, std::vector<int>> m;

    CartesianProduct<std::vector<int>, std::map<int, std::vector<int>>>
      c(i, m);

    return 0;
}
like image 198
StoryTeller - Unslander Monica Avatar answered Sep 24 '22 07:09

StoryTeller - Unslander Monica