0
namespace details {
template <std::size_t I = 0, typename Tuple, typename Function, typename... Args>
typename std::enable_if<I == std::tuple_size<Tuple>::value, void>::type ForEach(Tuple &t, Function f, Args &... args) {}

template <std::size_t I = 0, typename Tuple, typename Function, typename... Args>
typename std::enable_if<(I < std::tuple_size<Tuple>::value), void>::type ForEach(Tuple &t, Function f, Args &... args) {
    f(std::get<I>(t), args...);
    ForEach<I + 1>(t, f, args...);
}
}

An implementation for ForEach functionality for all types of a tuple is above. It calls f(tuple_type, args...)

However I want something like tuple_type.f(args...) where f and args are template arguments.

f would be a member function of all the types in the tuple, taking args... as arguments.

template <typename... Types>
class TupleManager {
    std::tuple<Types...> t;
    template <typename Function, typename... Args>
    void ForEach(Function f, Args& ... args) {
         details::ForEach<>(t, f, args...);
    }
}

Clarification: f needs to be a member function, i.e a function that takes the same name for all types in the tuple.

Eg:

struct A {
    void foo() {
        std::cout << "A's foo\n";
    }
};
struct B : A {
    void foo() {
        std::cout << "B's foo\n";
    }
};

struct C : A {
    void foo() {
        std::cout << "C's foo\n";
    }
};

But now I can't pass foo. Passing &A::foo print's A's foo. The requirement is to print A'foo for object of A in the tuple, B's foo for object of B in the tuple, and C's foo for object of C in the tuple.

Demo

themagicalyang
  • 2,493
  • 14
  • 21
  • I don't know what you are asking. "Something like" with *no description of what features of what you typed you actually want* is not very clear. What "like" that do you want, what do you need, etc? You want `f` to be between `tuple_type` and `args...`? You want to use exactly that syntax, where `f` happens to be the name of a common member function? You want exactly that punctuation? – Yakk - Adam Nevraumont Apr 06 '17 at 15:58
  • Think about how to call your function... `ForEach(myTuple, &C::foo)`... – Jarod42 Apr 06 '17 at 17:29
  • Change `f(std::get(t), args...);` to `std::get(t).f(args...)` and see Jarod's comment. – David G Apr 06 '17 at 20:17
  • Have provided a Wandbox link. PAssing &C::foo isn't viable. What is C? C is a type of the tuple. It's not known while calling ForEach. Only's foo is known, or rather that the name foo. – themagicalyang Apr 07 '17 at 03:57

1 Answers1

0

The beauty of std::for_each is in its disassociation of function application (on the elements of the range) from iteration (of the range). As such, one doesn't pass the arguments of the call to std::for_each (except for the callee itself that is already passed via the range). Having that in mind, you might want to consider using a different version of for_each that is closer to the std one. Check this one for example: iterate over tuple.

If you're up to a generalisation, you may want to use Jonathan Müller's tuple_iterator. That enables application std algorithms on std::tuples just as if std::tuple were a std container. In particular, you can use std::for_each for your desirable iteration.

Hossein
  • 111
  • 1
  • 5