Das Problem ist: Wir haben eine std::tuple<T1, T2, ...>
und wir haben eine Funktion f
, die wir für jedes Element nennen können, wo f
eine int
zurückkehrt, und wir wollen, dass diese Ergebnisse in einem Array speichern.
Beginnen sie mit einem konkreten Fall starten:
template <typename T> int f(T) { return sizeof(T); }
std::tuple<int, char, double> tup{42, 'x', 3.14};
std::array<int, 3> arr{ f(std::get<0>(tup)),
f(std::get<1>(tup)),
f(std::get<2>(tup)));
ausgenommen alle get
s auszuschreiben ist unbequem und redundante bestenfalls, fehleranfällig im schlimmsten Fall. Nehmen wir an, wir hatten einen Typ index_sequence<0, 1, 2>
. Das könnten wir verwenden das Array Initialisierung in eine variadische Expansion Pack zum Einsturz:
template <typename Tuple, size_t... Indices>
std::array<int, sizeof...(Indices)>
call_f_detail(Tuple& tuple, index_sequence<Indices...>) {
return { f(std::get<Indices>(tuple))... };
}
das, weil innerhalb der Funktion ist, wird f(std::get<Indices>(tuple))...
zu f(std::get<0>(tuple)), f(std::get<1>(tuple)), f(std::get<2>(tuple))
erweitert. Was genau wir wollen.
Das letzte Detail des Problems erzeugt nur diese bestimmte Indexsequenz. C 14 ++ tatsächlich gibt uns eine solche Utility namens make_index_sequence
template <typename Tuple>
std::array<int, std::tuple_size<Tuple>::value>
call_f(Tuple& tuple) {
return call_f_detail(tuple,
// make the sequence type sequence<0, 1, 2, ..., N-1>
std::make_index_sequence<std::tuple_size<Tuple>::value>{}
);
}
während der Artikel, den Sie einfach verknüpft wird erklärt, wie man ein solches metafunction implementieren könnte.
Bare
ist wahrscheinlich so etwas wie, von Luc Danton's answer:
template<typename T>
using Bare = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
'Bare' scheint etwas entlang der Linien von' remove_reference_t'. Beachten Sie, dass der Code auf der verknüpften Seite das Tupel durch Weiterleitungsverweis übernimmt, so dass "Tupel" ein Referenztyp sein kann und "tuple_size" bei Referenztypen nicht funktioniert. (Technisch wird das 'remove_cv' nicht benötigt.' Tuple_size' soll mit cv-qualifizierten 'tuple' funktionieren.) –
Große Antwort, wie immer. Ich fand eine mögliche Definition von "Bare" in [dieser Antwort] (http://stackoverflow.com/a/10615119/1274223), die so etwas wie "Decay_t" zu sein scheint. – Alejandro
In der Definition von call_f_detail, meinst du nicht 'f (std :: get (Tupel) ...)' anstatt 'f (std :: get (Tupel)) ...'? – einpoklum