Ist es möglich, class template argument deduction für eine Klasse C
aus der Definition einer der C
Mitgliederfunktionen zu verwenden? ... oder bin ich gezwungen, meine make_c
Hilfsklasse wie in C++ 03 zu schreiben?Vorlage Argument Typ Abzug aus innerhalb der Klassendefinition
Betrachten Sie diese minimiert und vereinfachte Szenario, das eine Kette von beliebigen Funktionsobjekte baut:
template <typename F>
struct node;
template <typename FFwd>
node(FFwd&&) -> node<std::decay_t<FFwd>>;
Die node
Klasse speichert ein Funktionsobjekt, das über perfekte Weiterleitung initialisiert wird. Ich brauche einen Deduktion Guide hier zu decay
den Typ der Funktion Objekt.
template <typename F>
struct node
{
F _f;
template <typename FFwd>
node(FFwd&& f) : _f{std::forward<FFwd>(f)}
{
}
template <typename FThen>
auto then(FThen&& f_then)
{
return node{[f_then = std::move(f_then)]
{
return f_then();
}};
}
};
Danach definiere ich node
‚s Konstruktor und eine Fortsetzungs .then
Elementfunktion, die einen neuen Knoten zurückgibt (seine Implementierung ist unsinnig, die Größe des Beispiels zu minimieren). Wenn ich .then
aufzurufen versuchen ...
auto f = node{[]{ return 0; }}.then([]{ return 0; });
... Ich erhalte einen unerwarteten Kompilierungsfehler:
prog.cc: In instantiation of 'node<F>::node(FFwd&&) [with FFwd = node<F>::then(FThen&&) [with FThen = main()::<lambda()>; F = main()::<lambda()>]::<lambda()>; F = main()::<lambda()>]':
prog.cc:27:22: required from 'auto node<F>::then(FThen&&) [with FThen = main()::<lambda()>; F = main()::<lambda()>]'
prog.cc:35:56: required from here
prog.cc:17:46: error: no matching function for call to 'main()::<lambda()>::__lambda1(<brace-enclosed initializer list>)'
node(FFwd&& f) : _f{std::forward<FFwd>(f)}
^
prog.cc:35:20: note: candidate: 'constexpr main()::<lambda()>::<lambda>(const main()::<lambda()>&)'
auto f = node{[]{ return 0; }}.then([]{ return 0; });
^
Dies geschieht, weil im Innern des Körper von node<F>::then
, node{...}
schafft eine Instanz mit dem Typ *this
- es löst keinen Argumenttyp Abzug aus. Ich bin daher gezwungen zu schreiben:
template <typename FThen>
auto then(FThen&& f_then)
{
auto l = [f_then = std::move(f_then)]{ return f_then(); };
return node<std::decay_t<decltype(l)>>{std::move(l)};
}
..., die den ganzen Zweck des Abzugs Führer besiegt.
Gibt es einen Weg, ich kann Klassenvorlage Argument Abzug hier ohne Einführung Code Repetition oder eine make_node
Funktion?
Duh, ich hatte das Gefühl, ich einfach etwas fehlte zu schreiben. Prost. Wird so bald wie möglich annehmen. –
Ist das Verfallen des Typs im Deduktionsleitfaden nutzlos? Oder wofür ist der "cleaner guide"? –
@ MárioFeroldi Wenn der Guide das Argument durch Weiterleiten der Referenz übernimmt, müssen Sie den Typ manuell dekadieren (für den Anwendungsfall im OP). Wenn es das Argument nach Wert nimmt, dann macht die Sprache den Zerfall für Sie und Sie müssen es nicht manuell zerlegen. –