I want to apply certain functionality to some elements of a tuple based on a given condition or constraint of the types.
Below is a small dummy example where I want to call a callback function for all the elements in the tuple that holds an arithmetic type. In my current solution, I use std::apply
and if constexpr
on the type constraint as the condition to call the callback.
However, I assume this is iterating through all the elements of the tuple?
And now I am wondering if there is an alternative to do this. In my head, it should be possible to select the indices of the elements of interest at compile-time, because all the types are known and then apply the functionality only for the elements at those indices. But I don't know if this is possible, nor how to translate this to code.
#include <iostream>
#include <string>
#include <tuple>
#include <type_traits>
template <typename... Args>
struct Foo {
using my_tuple = std::tuple<Args...>;
template <typename Fn>
void CallForArithmetic(Fn&& fn) {
auto arithmetic_call = [&]<typename T>(const T& x) {
if constexpr (std::is_arithmetic_v<T>) {
fn(x);
}
};
std::apply([&](auto&&... arg) { (arithmetic_call(arg), ...); }, tuple_);
};
private:
my_tuple tuple_;
};
int main() {
Foo<int, std::string> foo{};
int calls = 0;
// will be called only once for int type
foo.CallForArithmetic(
[&calls](const auto& arg) { std::cout << calls++ << '\n'; });
}