Ich möchte eine has_no_duplicates<...>
-Typ-Eigenschaft implementieren, die zu std::true_type
ausgewertet wird, wenn die übergebene Variantentyp-Liste keine doppelten Typen aufweist.
Nehmen wir an, für den Umfang dieser Frage möchte ich das mit Mehrfachvererbung machen.
Wenn eine Klasse mehr als einmal vom selben Typ erbt, tritt ein Fehler auf.
%Vor% Ich nahm an, ich hätte void_t
verwenden können, um diesen Fehler zu "erkennen", aber ich konnte keine funktionierende Lösung implementieren nach den Codebeispielen von cppreference .
Das habe ich versucht:
%Vor% Bei meinem dritten Versuch habe ich versucht, die Erweiterung von dup_helper<...>
mit einer Wrapper-Klasse zu verzögern, die dup_helper
als Template-Template-Parameter wie wrapper<dup_helper, ...>
verwendet und in void_t
erweitert hat.
Leider führten alle meine Versuche dazu, dass der oben erwähnte Fehler die Kompilierung immer verhinderte.
Ich nehme an, diese Art von Fehler ist nicht als "Substitutionsfehler" erkennbar, aber ich möchte eine Bestätigung.
Ist diese Art von Fehler tatsächlich nicht mit void_t
zu erkennen? (Wird es immer zu einem Kompilierungsfehler führen?)
Gibt es eine Möglichkeit, es zu erkennen, ohne dass die Kompilierung fehlschlägt? (Oder eine nicht void_t
Workaround, die immer noch den "multiple Vererbung Trick" verwendet)?
Wie @Canoninos bemerkt hat, ist das Problem:
es ist nicht die Deklaration von
dup_helper<T, T>
, die einen Fehler verursacht, sondern ihre Definition [...].
Oder in Standardese tritt der Fehler außerhalb des "unmittelbaren Kontexts" ( [temp.deduct] ) der Substitution auf:
8 - [...] Nur ungültige Typen und Ausdrücke im unmittelbaren Kontext des Funktionstyps und Seine Vorlagenparametertypen können zu einem Fehlschlagen des Abzugs führen. [ Hinweis: Die Bewertung der substituierten Typen Ausdrücke können zu Nebeneffekten wie der Instanziierung von Klassenvorlagenspezialisierungen und / oder führen Funktion Template-Spezialisierungen, die Generierung von implizit definierten Funktionen, etc. Solche Nebenwirkungen sind nicht im "unmittelbaren Kontext" und kann dazu führen, dass das Programm schlecht gebildet wird. - Endnote ]
Hier tritt der Fehler auf, während dup_helper<float, float>
instanziiert wird, also nicht im "unmittelbaren Kontext".
Ein mehrfacher Vererbungstrick, der deinem sehr nahe kommt, beinhaltet das Hinzufügen einer zusätzlichen Vererbungsschicht durch Indexieren der mehreren Basen:
%Vor%Dies gibt uns eine Hilfsklasse mit einer gültigen Definition, die aufgrund ihrer Mehrdeutigkeit instanziiert, aber nicht in ihre endgültigen Basisklassen umgewandelt werden kann:
%Vor%Beispiel .
Das ist meine Lösung mit Meta-Programmierung und Typ-Liste-Idiom. Ich benutze diesen Code als Teil meiner Bibliothek, die Reflektion für C ++ implementiert. Ich denke, es gibt keine Notwendigkeit in void_t oder Vererbung, diese Aufgabe zu lösen.
%Vor%Tags und Links c++ templates variadic-functions c++17 sfinae