Call template-function with types in a tuple (not values)

Advertisements

I would like to call a template function with no arguments for each type in a tuple. The code below shows exactly what the intention is.

My solution involves making a dummy instance of DataGroup(). I’d like to avoid this, as the types may not have a default constructor.

I’ve attempted to use std::declval<DataGroup>() instead, this results in
'std::declval': Symbol involving type with internal linkage not defined (in msvc).

#pragma once
#include <tuple>

template<typename T>
void do_something_based_on_the_type()
{
    // ...
}

template<template <typename...> typename Tuple, typename... Ts>
void do_something_based_on_the_types_in_a_tuple(Tuple<Ts...>)
{
    (do_something_based_on_the_type<Ts>(), ...);
}

void some_code()
{
    struct Dataset1 {};
    struct Dataset2 {};
    struct Dataset3 {};
    using DataGroup = std::tuple<Dataset1, Dataset2, Dataset3>;

    do_something_based_on_the_types_in_a_tuple(DataGroup()); // -> ugly? requires a dummy instantiation of the tuple
}



My preferred solution, based on two of the answers together:

namespace internal
{

template<template <typename...> typename Tuple, typename TemplateFunc, typename... Ts>
void call_per_type_in_tuple(std::type_identity<Tuple<Ts...>>, TemplateFunc f)
{
    (f.template operator () < Ts > (), ...);
}

}

template<typename Tuple, typename TemplateFunc>
void call_foreach_tuple_type(TemplateFunc f)
{
    internal::call_per_type_in_tuple(std::type_identity<Tuple>(), std::forward<TemplateFunc>(f));
}

void example()
{
    struct Dataset1 {};
    struct Dataset2 {};
    struct Dataset3 {};
    using DataGroup = std::tuple<Dataset1, Dataset2, Dataset3>;

    call_foreach_tuple_type<DataGroup>([]<typename T>()
    {
        // ...
    });
}

>Solution :

You can pass in std::type_identity which is always default-constructible

#include <type_traits>

template<template <typename...> typename Tuple, typename... Ts>
void do_something_based_on_the_types_in_a_tuple(std::type_identity<Tuple<Ts...>>)
{
    (do_something_based_on_the_type<Ts>(), ...);
}

using DataGroup = std::tuple<Dataset1, Dataset2, Dataset3>;
do_something_based_on_the_types_in_a_tuple(std::type_identity<DataGroup>());

Leave a ReplyCancel reply