Heim >Backend-Entwicklung >C++ >Wie kann ich Vorlagentypen in C auf bestimmte Vererbung oder Funktionalität beschränken?

Wie kann ich Vorlagentypen in C auf bestimmte Vererbung oder Funktionalität beschränken?

Barbara Streisand
Barbara StreisandOriginal
2024-12-31 04:58:09186Durchsuche

How Can I Restrict Template Types in C   to Specific Inheritance or Functionality?

So beschränken Sie eine Vorlage so, dass sie nur bestimmte Typen in C akzeptiert

In Java können generische Klassen so definiert werden, dass sie nur erbende Typen akzeptieren aus einer bestimmten Klasse:

public class ObservableList<T extends List> {
    /* ... */
}

Dies wird mithilfe der Erweiterungen erreicht Schlüsselwort.

Äquivalent in C

Im Gegensatz zu Java gibt es in C kein direktes Äquivalent zum Schlüsselwort „extens“ zum Einschränken von Vorlagen. Es gibt jedoch eine Möglichkeit, ähnliche Einschränkungen mithilfe des Typmerkmals std::is_base_of in C 11 zu erreichen:

#include <type_traits>

template<typename T>
class observable_list {
    static_assert(std::is_base_of<list, T>::value, "T must inherit from list");
    // code here..
};

Alternative Ansätze

Während dieser Ansatz funktioniert, es bricht mit den typischen C-Designprinzipien. Stattdessen kann es sinnvoller sein, merkmalsbasierte Einschränkungen zu verwenden:

#include <type_traits>

template<typename T>
class observable_list {
    static_assert(has_const_iterator<T>::value, "Must have a const_iterator typedef");
    static_assert(has_begin_end<T>::value, "Must have begin and end member functions");
    // code here...
};

template<typename T>
struct has_const_iterator : std::false_type {};

template<typename T>
struct has_const_iterator<T, Void<typename T::const_iterator>> : std::true_type {};

struct has_begin_end_impl {
    template<typename T, typename Begin = decltype(std::declval<const T&>().begin()),
                         typename End   = decltype(std::declval<const T&>().end())>
    static std::true_type test(int);
    template<typename... Args>
    static std::false_type test(...);
};

template<typename T>
struct has_begin_end : decltype(has_begin_end_impl::test<T>(0)) {};

using Void = typename void_<>::type;

template<typename... Args>
struct void_ {
    using type = void;
};

Dieser Ansatz definiert benutzerdefinierte Merkmale, um auf bestimmte Anforderungen zu prüfen (z. B. das Vorhandensein von const_iterator, begin- und end-Funktionen). Es bietet mehr Flexibilität und ermöglicht benutzerdefinierte Fehlermeldungen.

Das obige ist der detaillierte Inhalt vonWie kann ich Vorlagentypen in C auf bestimmte Vererbung oder Funktionalität beschränken?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn