mercredi 18 novembre 2020

How to do compile-time recursion over a given set of template template classes?

Aim: To do compile-time recursion over a given set of template template classes to compute a given function.

Problem: I could not devise how the template arguments should look like for run_tests function.

MWE: Please consider the following code example working for a given set of built-in types (This example is based on an answer in stackoverflow, which I couldn't find it back so far - I will add the link when I find it):

#include <tuple>
#include <type_traits>
#include <iostream>
#include <vector>

template<class Type>
void test(Type)
{
    // Do nothing
    std::cout<< "I survived 2020" << std::endl;
}

// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests
(
    const std::tuple<Tp...>& types
)
{}

template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests
(
    const std::tuple<Tp...>& types
)
{
    test(std::get<I>(types));

    run_tests<I + 1, Tp...>(types);
}


int main(int argc, char *argv[])
{

    const std::tuple<int, double> types    // working
    // const std::tuple                    // not working
    // <
    //     std::vector<std::vector<int>>,
    //     std::vector<std::vector<double>>
    // > types
    (
        std::make_tuple(nullptr, nullptr)
    );

    run_tests(types);

    return 0;
}

Attempts: I have commented out the commented piece of code above, i.e.:

// const std::tuple<int, double> types    // working
const std::tuple                          // not working
<
    std::vector<std::vector<int>>,
    std::vector<std::vector<double>>
> types

The above threw the following as the first compilation error:

error: no matching function for call to ‘std::tuple<std::vector<std::vector<int, 
std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, 
std::vector<std::vector<double, std::allocator<double> >, 
std::allocator<std::vector<double, std::allocator<double> > > > 
>::tuple(std::tuple<std::nullptr_t, std::nullptr_t>)’
 );

Aucun commentaire:

Enregistrer un commentaire