2014-11-16 7 views
5

Ich habe eine for_each-Schleife für Tupel gefunden, die nur über die Elemente iteriert und sie in eine Funktion übergibt.Kann eine generische Funktion über Tupel-Elemente angewendet werden?

namespace std { 
    template<int I, class Tuple, typename F> struct for_each_impl { 
    static void for_each(const Tuple& t, F f) { 
     for_each_impl<I - 1, Tuple, F>::for_each(t, f); 
     f(get<I>(t)); 
    } 
    }; 
    template<class Tuple, typename F> struct for_each_impl<0, Tuple, F> { 
    static void for_each(const Tuple& t, F f) { 
     f(get<0>(t)); 
    } 
    }; 
    template<class Tuple, typename F> 
    void for_each(const Tuple& t, F f) { 
    for_each_impl<tuple_size<Tuple>::value - 1, Tuple, F>::for_each(t, f); 
    } 
} 

.

auto t = std::make_tuple(Foo(),Bar(),Baz()); 
std::for_each(t,[](???){}); 

Wäre es möglich, eine generische Funktion wie diese zu haben?

std::for_each(t,[](T &&t){t.foo();}); 

Am Ende möchte ich nur etwas haben, das mit jedem Tupel funktioniert.

std::get<0>(t).foo(); 
std::get<1>(t).foo(); 
std::get<2>(t).foo(); 
... 

Vielleicht wäre dies mit Makros einfacher?

Antwort

9

In C++ 14 können Sie einen generic Lambda-Ausdruck verwenden:

for_each(t, [] (auto&& t) { std::forward<decltype(t)>(t).foo(); }); 

In C++ 11 können Sie Ihren eigenen Funktors erklären:

struct Lambda 
{ 
    template <typename T> 
    void operator()(T&& t) const { std::forward<T>(t).foo(); } 
}; 

for_each(t, Lambda{}); 

oder wenn, Stattdessen möchten Sie je nach dem Typ des Tupelelements, der gerade verarbeitet wird, eine andere Funktion anwenden. Dann ist wiederum ein benutzerdefinierter Funktor erforderlich:

struct Lambda 
{ 
    void operator()(const Foo& foo) const { foo.foo(); } 
    void operator()(const Bar& bar) const { bar.bar(); } 
    void operator()(const Baz& baz) const { baz.baz(); } 
}; 

for_each(t, Lambda{}); 

Und als eine Randnotiz: definieren Sie keine Funktionen innerhalb des Namespace std.

Verwandte Themen