Verwenden von 'void_t' zum Erkennen mehrfacher Vererbungstyp-Wiederholungsfehler

8

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.

%Vor%

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)?

    
Vittorio Romeo 14.08.2015, 18:57
quelle

2 Antworten

6

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 .

    
ecatmur 14.08.2015, 19:43
quelle
0

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%

DEMO

    
Elohim Meth 14.08.2015 20:44
quelle