Wie überprüft man, ob eine Klasse einen Standardkonstruktor hat, entweder public, protected oder private?

8

Ich muss überprüfen, ob eine Klasse C einen Standardkonstruktor hat, entweder implizit oder benutzerdefiniert, und entweder public , protected oder private .

Ich habe versucht, std::is_default_constructible<C>::value zu verwenden, was true zurückgibt, wenn C einen public Standardkonstruktor (entweder implizit oder benutzerdefiniert) hat, aber false , wenn C einen protected oder private Standardkonstruktor hat ( scheint jedoch das Standardverhalten zu sein.)

Gibt es eine Möglichkeit zu überprüfen, ob eine Klasse einen protected oder private Standardkonstruktor hat?

Hinweis (falls das helfen kann): Die Überprüfung wird von einer Funktion durchgeführt, die friend der zu prüfenden Klasse C ist.

Ich muss diese Prüfung durchführen, um Objekte zu erzeugen, die den nullptr Zeigern des m_objs Tupels entsprechen, Mitglied eines Foo Objekts (partielle Foo Definition unten):

%Vor%

welches als:

verwendet werden soll %Vor%

Beispiel oben behauptet, weil std::is_default_constructible<B>::value falsch ist, obwohl B einen [privaten] Standard-Ctor und Foo<A,B> einen Freund von B hat.

    
shrike 13.05.2016, 13:33
quelle

3 Antworten

3

Ich werde ein vereinfachtes Beispiel vorstellen, um die Dinge zu vereinfachen. Dann können Sie es an Ihre Foos-Klasse anpassen. Die Idee ist, meine Templates-Klasse wie folgt zu spezialisieren:

%Vor%

Beachten Sie, dass der Kandidat std :: true_type immer gültig ist, solange X einen Standardkonstruktor hat, unabhängig davon, ob es privat, geschützt oder öffentlich ist. Testen Sie es jetzt

%Vor%     
linuxfever 13.05.2016, 15:53
quelle
3

Das Problem besteht darin, dass, wenn eine Klasse weder einen öffentlichen noch einen geschützten oder privaten Standardkonstruktor hat, die einfache Standarddefinition einer Instanz einen Kompilierungsfehler und keine Laufzeitausnahme ergibt. Der Test ist also einfach: Wenn dieser Ausdruck in einer Friend-Funktion C c; kompiliert wird, hat die Klasse einen Standard-Ctor, entweder public, protected oder private.

Siehe Beispielcode:

%Vor%

Aber ich konnte mir einen Laufzeittest nicht vorstellen ...

    
Serge Ballesta 13.05.2016 13:56
quelle
2

Mein Verständnis ist, dass Sie überprüfen möchten, ob Ihr friend standardmäßig eine Klasse erstellen kann. Der Trick ist, dass Sie SFINAE innerhalb des Umfangs der Funktion friend haben müssen. Um dies zu tun, benötigen Sie Vorlagen. Um lokale Vorlagen zu haben, benötigen Sie generische Lambdas.

Wir beginnen mit einem Overloader, in den wir mehrere Lambdas eingeben können. Vielleicht gibt es einen besseren Weg, dies zu schreiben:

%Vor%

Dann übergeben Sie überladene, generische, SFINAE-d Lambdas (C ++ 14 erforderlich). Sagen wir, wir haben:

%Vor%

Dann könnten wir schreiben:

%Vor%

Wenn works ein Freund ist, ist die erste Überladung praktikabel und bevorzugt - also bekommst du das, was ein Q erzeugt, weil es möglich ist. Wenn works kein Freund ist, ist die erste Überladung nicht praktikabel und Sie erhalten die zweite Überladung.

Der Schlüssel ist, dass wir die Konstruktion von Q (der typename decltype(x)::type() Teil) innerhalb von works() testen - also wird es entweder von Freundschaft gedeckt sein.

Für Ihre spezielle Verwendung wäre das also:

%Vor%     
Barry 13.05.2016 14:32
quelle

Tags und Links