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

Benutzer-Avatar
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

Benutzer-Avatar
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>

1012970cookie-checkPartielle Ableitung von Klassenvorlagenargumenten in C++17

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy