Betrachten Sie den folgenden Code, der eine Klasse zum Speichern von Funktionen erstellen.Perfekte Weiterleitung von Funktionen zum Erstellen einer Funktionsliste Klasse
// Function list class
template <class... F>
struct function_list
{
template <class... G>
constexpr function_list(G&&... g) noexcept
: _f{std::forward<G>(g)...}
{
}
std::tuple</* F... OR F&&... */> _f;
};
// Function list maker
template <class... F, class R = /* Can we compute the return type here? */>
constexpr R make_function_list(F&&... f)
{
return function_list<
/* decltype(std::forward<F>(f))...
* OR F...
* OR F&&...
*/>(std::forward<F>(f)...);
}
würde ich diese Funktionen wie perfekt weitergeleitet werden (unabhängig davon, ob sie Funktionszeiger, functors, Lambda-Ausdrücke ...). Aber ich verstehe nicht genau, was hinter std::forward
und universellen Referenzen passiert. In dem obigen Code, habe ich drei Fragen:
- Sollte
_f
vom Typ seinerstd::tuple<F...>
oderstd::tuple<F&&...>
- Ist es möglich, den Rückgabetyp
R
in der Vorlage Parameterliste abzuleiten (weil es zu tun (und warum?) manuell stattauto/decltype(auto)
wäre hilfreich, zu verstehen, was los ist) - In dem Hersteller, was das
function_list
Template-Argument sein sollte:decltype(std::forward<F>(f)...)
,F
oderF&&...
(und warum)
Hinweis: Der Konstruktor function_list
soll nicht direkt aufgerufen werden, stattdessen erledigt make_function_list
die Aufgabe.
EDIT: Ist dieser Fall sicher, wenn die operator()
von function_list
(hier nicht dargestellten) guaranted ist nicht auf der gleichen Anweisung aufgerufen werden?
template <class... F>
constexpr function_list<F...> make_function_list(F&&... f)
{
return function_list<F&&...>(std::forward<F>(f)...);
}
Sie würden mit ziemlicher Sicherheit ** nicht ** wollen, dass sie 'F sein &&'. – SergeyA
1) 'tuple' 2) Sie würden 'R' in der Vorlagenliste nicht benötigen, Sie kennen bereits den Rückgabetyp' function_list '3)' F && 'weil es eine Weiterleitungsreferenz ist, die sowohl an rvalue als auch bindet lvalue refs (Sie sagten, Sie wollten eine perfekte Weiterleitung, also so würden Sie es bekommen) –
AndyG
Wenn Sie garantieren können, dass der Funktionsaufrufoperator innerhalb derselben Anweisung wie 'make_function_list' aufgerufen wird, können Sie' F && 'verwenden (Sie können drücke das mit einem ref-Qualifikationsmerkmal, '&&', auf 'operator()') –