Partielle Ableitung von Klassenvorlagenargumenten in C++17
Lesezeit: 3 Minuten
Im folgenden Beispiel verwenden wir das C++17-Feature „Class template argument deduction“, um dies abzuleiten val ist vom Typ Base<int, double, bool>:
template<class T, class U, class V>
struct Base {
Base(T, U) { };
Base(T, U, V) { };
Base(V) { };
};
void func() {
Base val(1, 4., false);
}
Ist es nun möglich, die Vorlagenargumente teilweise anzugeben und die verbleibenden abzuleiten? Effektiv etwas wie diese:
Base<V = bool> val1(1, 4.); // U & V deduced --> Base<int, double, bool>
Base<T = bool, T = int> val2(5.); // V deduced --> Base<bool, int, double>
Ich habe versucht zB
template<class T, class U> using Base2 = Base<T, U, double>;
void func() {
NewBase2 val(1, 2);
}
aber es kompiliert nicht: 'Base2': use of alias template requires template argument list.
Teilabzug irgendwie möglich? Wenn es nicht direkt möglich ist, gibt es gute Workarounds?
In dem angegebenen Beispiel können Sie angeben T und haben U und haben V abgeleitet oder angeben T und Uund haben V abgeleitet. Sehen Sie das Muster? Es wäre schön, benannte Template-Parameter in C++ zu haben, leider haben wir das nicht.
– Sam Varshavchik
19. August 2019 um 20:35 Uhr
Related: C++ – Teilabzug der C++17-Klassenvorlage
– Benutzer202729
12. Oktober 2021 um 5:41 Uhr
NathanOliver
CTAD (Class Template Argument Deduction) ist derzeit ein Alles-oder-Nichts-Prozess. Sie geben entweder nichts an und lassen den Compiler alle Argumente ableiten, oder Sie geben alle Argumente an und nehmen den Compiler aus der Schleife.
Es gibt ein Papier (P1021R0), die dies und mehr verlangt, aber noch nicht angenommen wurde. Es gab ein Papier, das eine teilweise Spezialisierung forderte, aber nach Überarbeitungen wurde es entfernt. Die neuste Überarbeitung enthält immer noch einen Vorschlag, eine CTAD-Funktion zu haben, wenn ein Alias verwendet wird.
Per @Barry Support für Alias-Vorlagen (P1814) und Aggregate (P1816) wurden dem Arbeitsentwurf für C++20 hinzugefügt. Es wurde keine Unterstützung für partielles CTAD oder CTAD mit geerbten Konstruktoren hinzugefügt.
Die neueste Überarbeitung des Papiers ist P1021die in zwei verschiedene Papiere aufgeteilt wurde: P1814 für Alias-Vorlagen und P1816 für Aggregate. Beide wurden dem Arbeitsentwurf für C++20 hinzugefügt. Es wird weder partielles CTAD noch Unterstützung für geerbte Konstruktoren geben.
– Barri
19. August 2019 um 20:43 Uhr
@Barry Danke für die Quellen. Ich füge das hinzu.
– NathanOliver
19. August 2019 um 20:44 Uhr
Jarod42
Sie können einen Abzugsleitfaden wie folgt hinzufügen:
template<class T, class U, class V>
Base(T, U) -> Base<T, U, bool>;
template<class V>
Base(V) -> Base<bool, int, V>;
welches erlaubt
Base val1(1, 4.); // Base<int, double, bool>
Base val2(5.); // Base<bool, int, double>
Wenn Sie das “Standard”-Template angeben möchten, können Sie den alten Weg mit verwenden make_
template <typename V, typename T, typename U>
Base<T, U, V> make_Base(T t, U u)
{
return Base<T, U, V>{t, u};
}
template <typename T, typename U, typename V>
Base<T, U, V> make_Base(V v)
{
return Base<T, U, V>{v};
}
auto val1 = make_Base<bool>(1, 4.); // Base<int, double, bool>
auto val2 = make_Base<bool, int>(5.); // Base<bool, int, double>
10129700cookie-checkPartielle Ableitung von Klassenvorlagenargumenten in C++17yes
In dem angegebenen Beispiel können Sie angeben
T
und habenU
und habenV
abgeleitet oder angebenT
undU
und habenV
abgeleitet. Sehen Sie das Muster? Es wäre schön, benannte Template-Parameter in C++ zu haben, leider haben wir das nicht.– Sam Varshavchik
19. August 2019 um 20:35 Uhr
Related: C++ – Teilabzug der C++17-Klassenvorlage
– Benutzer202729
12. Oktober 2021 um 5:41 Uhr