Ich habe so etwas fälschlicherweise in C ++ gemacht, und es funktioniert. Warum kann ich das tun?
int main(int argc, char** argv) {
struct MyStruct
{
int somevalue;
};
MyStruct s;
s.somevalue = 5;
}
Nachdem ich das getan hatte, erinnerte ich mich daran, dass ich vor langer Zeit irgendwo über diesen Trick gelesen hatte, als eine Art funktionales Programmierwerkzeug für C ++, aber ich kann mich nicht erinnern, warum dies gültig ist oder wo ich es gelesen habe.
Antworten auf beide Fragen sind willkommen!
Hinweis: Obwohl ich beim Schreiben der Frage keine Verweise auf diese Frage erhalten habe, weist die aktuelle Seitenleiste darauf hin, sodass ich sie hier als Referenz einfügen werde. In beiden Fällen ist die Frage anders, könnte aber nützlich sein.
c++
data-structures
functional-programming
Robert Gould
quelle
quelle
Antworten:
[EDIT 18/4/2013]: Glücklicherweise wurde die unten erwähnte Einschränkung in C ++ 11 aufgehoben, sodass lokal definierte Klassen schließlich nützlich sind! Vielen Dank an Kommentator Bambus.
Die Möglichkeit, Klassen lokal zu definieren, würde das Erstellen benutzerdefinierter Funktoren (Klassen mit
operator()()
z. B. Vergleichsfunktionen zum Übergeben anstd::sort()
oder "Schleifenkörper", mit denen verwendet werden sollstd::for_each()
) wesentlich komfortabler machen.Leider verbietet C ++ die Verwendung lokal definierter Klassen mit Vorlagen , da diese keine Verknüpfung haben. Da die meisten Anwendungen von Funktoren Vorlagentypen umfassen, die als Vorlage für den Funktortyp dienen, können lokal definierte Klassen hierfür nicht verwendet werden. Sie müssen sie außerhalb der Funktion definieren. :(
[EDIT 1/11/2009]
Das relevante Zitat aus dem Standard lautet:
quelle
Eine Anwendung lokal definierter C ++ - Klassen befindet sich im Factory-Entwurfsmuster :
Sie können dies jedoch auch mit einem anonymen Namespace tun.
quelle
Es ist tatsächlich sehr nützlich, um einige stapelbasierte Ausnahmesicherheitsarbeiten durchzuführen. Oder allgemeine Bereinigung von einer Funktion mit mehreren Rückgabepunkten. Dies wird häufig als RAII-Idiom (Resource Acquisition is Initialzation) bezeichnet.
quelle
Cleaner cleaner();
Ich denke, dies wird eher eine Funktionsdeklaration als eine Objektdefinition sein.Cleaner cleaner;
oder schreibenCleaner cleaner{};
.Warum eigentlich nicht? A
struct
in C (bis in die Anfänge der Zeit) war nur eine Möglichkeit, eine Datensatzstruktur zu deklarieren. Wenn Sie eine möchten, können Sie sie dort deklarieren, wo Sie eine einfache Variable deklarieren würden.Wenn Sie dies getan haben, denken Sie daran, dass ein Ziel von C ++ darin bestand, wenn möglich mit C kompatibel zu sein. So blieb es.
quelle
Es wird zum Beispiel in Abschnitt "7.8: Lokale Klassen: Klassen innerhalb von Funktionen" von http://www.icce.rug.nl/documents/cplusplus/cplusplus07.html erwähnt, der es eine "lokale Klasse" nennt und es sagt " kann in fortgeschrittenen Anwendungen mit Vererbung oder Vorlagen sehr nützlich sein ".
quelle
Es dient zum Erstellen von Arrays von Objekten, die ordnungsgemäß initialisiert wurden.
Ich habe eine Klasse C, die keinen Standardkonstruktor hat. Ich möchte ein Array von Objekten der Klasse C. Ich finde heraus, wie diese Objekte initialisiert werden sollen, und leite dann eine Klasse D von C mit einer statischen Methode ab, die das Argument für das C im Standardkonstruktor von D bereitstellt:
In diesem Beispiel wird der Einfachheit halber ein trivialer Nicht-Standard-Konstruktor und ein Fall verwendet, in dem die Werte zur Kompilierungszeit bekannt sind. Es ist einfach, diese Technik auf Fälle zu erweitern, in denen ein Array von Objekten mit Werten initialisiert werden soll, die nur zur Laufzeit bekannt sind.
quelle
D*
Parameter verwendet), wird dies stillschweigend unterbrochen, wenn D tatsächlich größer als C ist (Ich denke ...)