Ich würde gerne verstehen, wie Ableitungen mit universellen Referenzen und std::forward
arbeiten, insbesondere um perfekt Weiterleitung Wrapper zu erstellen. Der folgende Code enthält einen Code zum Experimentieren mit einem Funktor-Wrapper in zwei Fällen: einen mit einem impliziten Deduktionsleitfaden und einen mit einem expliziten Deduktionsleitfaden.Perfekte Weiterleitung mit Klasse Vorlage Argument Abzug
Ich habe eine Menge &&
und std::forward
in Kommentare eingefügt, weil ich nicht weiß, wo sie benötigt werden, um eine perfekte Weiterleitung zu erreichen. Ich würde gerne wissen, wo ich sie hinstellen soll und wo sie nicht benötigt werden.
// Case with not conversion constructor
template <class F>
struct functor1
{
explicit constexpr functor1(F/*&&*/ f)
noexcept(std::is_nothrow_copy_constructible_v<F/*&&*/>)
: _f(/*std::forward<F>(*/f/*)*/)
{}
template <class... Args>
constexpr operator()(Args&&... args)
noexcept(std::is_nothrow_invocable_v<F/*&&*/, Args/*&&*/...>)
{
/*std::forward<F>(*/_f/*)*/(std::forward<Args>(args)...);
}
private: F/*&&*/ _f;
};
// Case with a conversion constructor
template <class F>
struct functor2
{
template <class G>
explicit constexpr functor2(G&& g)
noexcept(std::is_nothrow_constructible_v<G/*&&*/, F/*&&*/>)
: _f(/*std::forward<G>(*/g/*)*/)
{}
template <class... Args>
constexpr operator()(Args&&... args)
noexcept(std::is_nothrow_invocable_v<F/*&&*/, Args/*&&*/...>)
{
/*std::forward<F>(*/_f/*)*/(std::forward<Args>(args)...);
}
private: F/*&&*/ _f;
};
template <class G>
functor2(G&&) -> functor2<G/*&&*/>;
EDIT: Aus Gründen der Einfachheit, und weil es nicht der Punkt der Frage ist, in den vorhergehenden Beispielen, betrachten wir, dass F
und G
sind Funktion dh Klassen/Strukturen mit einem operator()
Objekte.