After a few years of web development, I'm working in C++ (14) again and decided to have some "dynamically typed functional fun" with template metaprogramming.
I have implemented map
and each
over tuples:
template <typename Tuple, typename Func, size_t... index>
void tuple_each_internal(Tuple const & tuple, Func func, index_sequence<index...>)
{
auto res = {
(func(get<index>(tuple)), nullptr)...
};
}
template <typename Tuple, typename Func, typename Indices = make_index_sequence<tuple_size<Tuple>::value>>
void tuple_each(Tuple const & tuple, Func func)
{
tuple_each_internal(tuple, func, Indices());
}
struct demo_functor_each {
/* Case #1: "Each" callback */
template <typename T>
void operator ()(T&& t) { ; }
/* Case #2: "Each with index as run-time parameter" callback */
//template <typename T>
//void operator ()(const size_t index, T&& t) { ; }
/* Case #3: "Each with index as compile-time parameter" callback */
//template <typename T, size_t index>
//void operator ()(T&& t) { ; }
};
void Example_Usage()
{
tuple<int, bool, string> t;
tuple_each(t, demo_functor_each());
}
And a similar implementation of map
.
Case #1 passes syntax check (I haven't tried running it yet).
Case #2 also passes syntax check, with tuple_each_internal
modified to pass the index as a function parameter: func(index, get<index>(tuple))
.
Case #3 is superior to case #2 in that the value of index
can be passed to other templates at compile time (e.g. get<index>(tuple)
), which is not possible in case #2.
I have been unable to implement case #3.
Given the callback signature:
template <typename T, size_t index>
void operator ()(T&& t) { ; }
I tried this as tuple_each_internal
:
auto res = {
(func<typename tuple_element<index, Tuple>::type, index>(get<index>(tuple)), nullptr)...
};
$ clang++ -std=c++14 tuple_iteration.h
error: expected '(' for function-style cast or type construction
auto res = { (func<typename tuple_element<index, Tuple>::type, index>(get<index>(tuple)), nullptr)... };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
$ g++ -std=c++14 tuple_iteration.h
error: expected ‘(’ before ‘,’ token
auto res = { (func<typename tuple_element<index, Tuple>::type, index>(get<index>(tuple)), nullptr)... };
^
It should be:
auto res = {
(func.template operator()<const typename tuple_element<index, Tuple>::type&, index>(get<index>(tuple)),
nullptr)...
};
Simpler with
/* Case #4: "Each with index as compile-time parameter" callback */
template <size_t index, typename T>
void operator ()(T&& t);
where code becomes:
auto res = {
(func.template operator()<index>(get<index>(tuple)),
nullptr)...
};
or even
template <size_t N, typename T>
void operator ()(std::integral_constant<std::size_t, N>, T&& t);
which results in
auto res = {
(func(std::integral_constant<std::size_t, index>{}, get<index>(tuple)),
nullptr)...
};