Ich versuche, eine Funktion mithilfe von Vorlagen zu definieren, und möchte, dass der Typname entweder int oder anEnum ist (eine bestimmte Aufzählung, die ich definiert habe). Ich habe Folgendes versucht, bin aber gescheitert:
template <int | anEnum T> // or <int T, anEnum T> or <int, anEnum T>
bool isFunction(const T &aVariable){}
Ich versuche, Vorlagen zu verwenden, anstatt zwei überladene Funktionen zu definieren. Ich würde es vorziehen, wenn die Funktion wie folgt aufgerufen würde, ohne dass der Programmierer den Typ berücksichtigen müsste
isFunction(aVariable) // and not isFunction<int> (aVariable) nor isFunction<anEnum> (aVariable)
Grundsätzlich möchte ich, dass diese Funktion für int- und aNum-Typen als Vorlage verwendet wird. Ich habe danach gesucht, konnte aber keine Antwort finden. Was kann ich vermissen? Vielen Dank,
false
für andere Typen zurückkehren oder die Funktion für andere Typen nicht instanziieren ?Antworten:
Zusätzlich zur Nicht-C ++ 20-Antwort würde ich Ihnen die folgende Implementierung vorschlagen , wenn Sie zufällig in der Lage sind, C ++ 20 und seine
concepts
Funktion zu verwenden :Demo
AKTUALISIEREN
Laut dem Kommentar von @RichardSmith gibt es hier einen skalierbareren und wiederverwendbaren Ansatz:
quelle
template<typename T, typename ...U> concept one_of = (std::is_same_v<T, U> || ...);
template<one_of<int, MyEnum> T> bool isFunction(T const& aVariable) {
Es gibt verschiedene Möglichkeiten, dies zu erreichen. Alle beinhalten die Verwendung des
type_traits
Headers. Sie können beispielsweise die fraglichen Typen im Hauptteil der Funktion statisch bestätigen.Wenn Sie diese Funktion unter anderen Überlastungen berücksichtigen müssen, kann eine SFINAE-Technik verwendet werden.
Dadurch wird die Funktion aus einem Überlastungssatz entfernt, bevor sie aufgerufen wird, wenn die Typen nicht übereinstimmen. Wenn Sie dieses Verhalten jedoch nicht benötigen, ermöglicht eine statische Zusicherung eine programmiererfreundlichere Fehlermeldung.
quelle
Was ist mit dieser Lösung? Ein Code mit der Funktion wird kompiliert, wenn der Typ T Ihren Anforderungen entspricht. Andernfalls ist die statische Zusicherung fehlgeschlagen.
quelle
isFunction(std::string_view)
). Die Signatur ist weiterhin eine gültige Übereinstimmung, aber die Instanziierung verursacht einen Fehler.Ich habe https://stackoverflow.com/a/60271100/12894563 verbessert Antwort auf . 'If constexpr' kann in dieser Situation helfen:
isFunction (1L) schlägt fehl, da keine überladene Funktion oder ein Zweig 'if constexpr' vorhanden ist.
UPDATE: Fehler behoben
https://godbolt.org/z/eh4pVn
quelle
static_assert(false, ...)
ist schlecht geformter NDR, ohne überhaupt verwendet zu werden. Wenn Sie Glück haben, wird Ihr Compiler Ihnen sofort mitteilen, wie es Clang tut: godbolt.org/z/m_Gk9n